Файл forms.php в Cotonti
содержит функции и методы для генерации различных типов HTML-форм и управления ими, такие как поля ввода, текстовые области, выпадающие списки и другие элементы
Файл forms.php в системной папке Cotonti CMF, как правило, содержит функции и методы для генерации различных типов HTML-форм и управления ими, такие как поля ввода, текстовые области, выпадающие списки и другие элементы пользовательского интерфейса. Этот файл используется для построения и обработки данных форм, которые используются на страницах сайта, управляемого фреймворком Cotonti.
Основное назначение:
Функции в этом файле обеспечивают удобное создание HTML-форм с использованием шаблонов, которые могут быть адаптированы с помощью кастомных параметров и строк ресурсов. Эти функции позволяют динамически генерировать элементы управления формы в зависимости от переданных параметров (например, значения, имена, атрибуты, ошибки), а также поддерживают множество кастомизаций (например, дополнительные атрибуты, специфические строки ресурсов и т. д.).
Суть содержания кода:
-
Генерация формы: Функции, такие как
cot_inputbox(),cot_textarea(),cot_selectbox(), и другие — это абстракции для создания различных типов элементов формы (ввод, текстовые области, выпадающие списки, чекбоксы и т. д.). -
Использование строк ресурсов (resource strings): Для отображения формы и её элементов используется система строк ресурсов (например, через
cot_rc()), что позволяет легко адаптировать и локализовать форму для разных языков и нужд сайта. -
Дополнительные атрибуты и кастомизация: Множество функций принимает параметры для настройки атрибутов HTML-элементов, таких как
attrs, что позволяет гибко настроить внешний вид и поведение формы. -
Обработка ошибок: В коде также предусмотрены механизмы для отображения ошибок формы, что полезно для валидации ввода данных пользователем.
-
Реализация дополнительных настроек: Некоторые функции включают поддержку дополнительных настроек, таких как скрытые поля, чекбоксы для удаления файлов и опции для отображения данных с учётом прав доступа (например, отображение только публичных категорий).
Характеристика стиля PHP:
-
Функциональный стиль: Код написан в основном в процедурном стиле, с использованием функций, которые выполняют отдельные задачи. Это типично для старых версий PHP и большинства фреймворков, использующих подобный подход.
-
Использование глобальных переменных: В некоторых местах используется доступ к глобальным переменным через
global, что может указывать на менее структурированный подход по сравнению с объектно-ориентированным программированием (ООП). -
Шаблоны и строки ресурсов: Код активно использует систему шаблонов и строк ресурсов (
cot_rc), что позволяет отделить логику работы с данными от визуальной части. Это способствует лёгкости локализации и кастомизации формы. -
Минимальное использование ООП: В коде нет явных объектов или классов, что указывает на отсутствие использования ООП. Вместо этого используются глобальные массивы и функции для управления состоянием формы и вывода данных.
-
Гибкость и расширяемость: Код содержит механизмы для расширения через плагины (
cot_getextplugins) и поддержку пользовательских настроек (например, кастомных строк ресурсов и атрибутов).
Заключение:
Основное назначение файла forms.php заключается в создании и обработке форм, предоставляя гибкие функции для генерации элементов формы с учётом всех необходимых параметров и кастомизаций. Стиль программирования можно охарактеризовать как функциональный, с элементами процедурного подхода.
/**
* API для генерации HTML-форм
*
* @package API - Forms // Пакет для работы с API создания форм
* @copyright (c) Cotonti Team // Авторство принадлежит команде Cotonti
* @license https://github.com/Cotonti/Cotonti/blob/master/License.txt // Лицензия на использование
*/
defined('COT_CODE') or die('Wrong URL'); // Защита от прямого доступа к файлу
/**
* Регистрирует экземпляры текстовых областей, чтобы информировать редакторы RichText о необходимости их загрузки
*/
$cot_textarea_count = 0; // Счётчик для текстовых областей, инициализируется как 0
/**
* Генерирует HTML-код для чекбокса
* @param bool $chosen Состояние чекбокса (включён/выключен) // Указывает, выбран ли чекбокс
* @param string $name Имя атрибута input // Имя поля, связанного с чекбоксом
* @param string $title Текст рядом с чекбоксом // Подпись к чекбоксу
* @param mixed $attrs Дополнительные атрибуты (строка или массив) // Атрибуты для тега input
* @param string $value Значение поля input (по умолчанию '1') // Значение чекбокса, отправляемое на сервер
* @param string $custom_rc Пользовательский ресурс строки // Настраиваемый ресурс оформления
* @return string Возвращает HTML-код для чекбокса
*/
function cot_checkbox($chosen, $name, $title = '', $attrs = '', $value = '1', $custom_rc = '')
{
global $R; // Глобальный массив с ресурсами для оформления
$input_attrs = cot_rc_attr_string($attrs); // Конвертируем атрибуты в строку
$value_off = (is_array($value)) ? $value[0] : 0; // Если значение передано массивом, берём первый элемент как "выключенное" значение
$value = (is_array($value)) ? $value[1] : $value; // Если значение передано массивом, берём второй элемент как "включённое" значение
$chosen = cot_import_buffered($name, $chosen); // Проверяем наличие сохранённого значения из буфера
$checked = $chosen ? ' checked="checked"' : ''; // Если выбран, добавляем атрибут checked
$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name; // Проверяем, соответствует ли имя полю массива, и извлекаем базовое имя
$rc = empty($R["input_checkbox_{$rc_name}"]) ? (empty($custom_rc) ? 'input_checkbox' : $custom_rc) : "input_checkbox_{$rc_name}"; // Определяем, какой ресурс использовать для оформления
return cot_rc($rc, array( // Генерируем HTML-код, используя ресурс
'value' => htmlspecialchars(cot_import_buffered($name, $value)), // Применяем значение, экранируя специальные символы
'value_off' => $value_off, // Добавляем значение "выключено"
'name' => $name, // Указываем имя чекбокса
'checked' => $checked, // Если выбран, добавляем соответствующий атрибут
'title' => $title, // Устанавливаем подпись чекбокса
'attrs' => $input_attrs // Вставляем дополнительные атрибуты
));
}
/**
* Генерирует HTML-код для элемента формы на основе строки ресурса
*
* @param string $type Тип поля: text, checkbox, button, file, hidden, image, password, radio, reset, submit // Определяет тип создаваемого элемента формы
* @param string $name Имя поля ввода // Имя атрибута name для поля
* @param string $value Значение, введённое в поле // Значение, передаваемое в поле ввода
* @param string|array<string, string> $attrs Дополнительные атрибуты (строка или ассоциативный массив) // Указывает дополнительные параметры для элемента
* @param string $custom_rc Настраиваемый ресурс строки // Уникальный ресурс для кастомного оформления
* @return string Возвращает HTML-код для элемента формы
*/
function cot_inputbox($type, $name, $value = '', $attrs = '', $custom_rc = '')
{
$input_attrs = cot_rc_attr_string($attrs); // Преобразует массив или строку атрибутов в строку для HTML
$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name; // Проверяет, является ли имя элементом массива, и выделяет базовое имя
$rc = empty(Cot::$R["input_{$type}_{$rc_name}"]) // Если ресурс не найден в глобальном массиве ресурсов
? (empty($custom_rc) ? "input_{$type}" : $custom_rc) // Используем стандартный ресурс для текущего типа или переданный пользовательский ресурс
: "input_{$type}_{$rc_name}"; // Если ресурс определён для данного имени, используем его
if (!isset(Cot::$R[$rc]) && empty($custom_rc)) { // Если ресурс не задан, а пользовательский ресурс не передан
$rc = 'input_default'; // Используем ресурс по умолчанию
}
$msgSeparate = isset(Cot::$cfg['msg_separate']) ? Cot::$cfg['msg_separate'] : false; // Проверяем, включена ли раздельная обработка сообщений об ошибках
$error = $msgSeparate ? cot_implode_messages($name, 'error') : ''; // Если включено, собираем сообщения об ошибках для данного поля
return cot_rc( // Генерируем HTML-код, используя ресурс оформления
$rc, // Имя ресурса для генерации
[
'type' => $type, // Указываем тип элемента формы
'name' => $name, // Имя элемента формы
'value' => htmlspecialchars((string) cot_import_buffered($name, $value)), // Значение поля, экранированное от специальных символов
'attrs' => $input_attrs, // Дополнительные атрибуты, преобразованные в строку
'error' => $error, // Текст сообщения об ошибке, если он существует
]
);
}
/**
* Генерирует группу переключателей (radio buttons)
*
* @param string $chosen Выбранное значение // Значение, которое будет отмечено как выбранное
* @param string $name Имя поля ввода // Имя атрибута name для группы переключателей
* @param array $values Доступные варианты // Массив значений для переключателей
* @param array $titles Заголовки для вариантов // Массив заголовков, отображаемых рядом с переключателями
* @param mixed $attrs Дополнительные атрибуты (строка или массив) // Указывает дополнительные параметры
* @param string $separator Разделитель между переключателями, по умолчанию берётся из $R['input_radio_separator'] // Разделитель между элементами
* @param string $custom_rc Пользовательский ресурс строки // Уникальный ресурс для кастомного оформления
* @param bool $htmlspecialcharsBypass Пропустить использование htmlspecialchars() для заголовков и значений // Позволяет передавать необработанные HTML-данные
* @return string Возвращает HTML-код для группы переключателей
*/
function cot_radiobox(
$chosen,
$name,
$values,
$titles = [],
$attrs = '',
$separator = '',
$custom_rc = '',
$htmlspecialcharsBypass = false
) {
if (!is_array($values)) { // Проверяем, является ли $values массивом
$values = explode(',', $values); // Если нет, преобразуем строку в массив, разделяя по запятым
}
if (!is_array($titles)) { // Проверяем, является ли $titles массивом
$titles = explode(',', $titles); // Если нет, преобразуем строку в массив
}
$use_titles = count($values) == count($titles); // Проверяем, совпадает ли количество значений и заголовков
$input_attrs = cot_rc_attr_string($attrs); // Преобразуем атрибуты в строку для HTML
$chosen = cot_import_buffered($name, $chosen); // Проверяем, не было ли ранее сохранённого значения для данного имени
if (empty($separator)) { // Если разделитель не указан
$separator = Cot::$R['input_radio_separator']; // Устанавливаем разделитель из глобального ресурса
}
$i = 0; // Счётчик для элементов
$result = ''; // Переменная для хранения HTML-кода
$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name; // Извлекаем базовое имя из имени массива
$rc = empty(Cot::$R["input_radio_{$rc_name}"]) // Проверяем, существует ли ресурс для имени
? (empty($custom_rc) ? 'input_radio' : $custom_rc) // Используем стандартный ресурс или пользовательский ресурс, если он указан
: "input_radio_{$rc_name}"; // Если есть специфический ресурс для имени, используем его
foreach ($values as $k => $value) { // Проходим по всем значениям
$checked = ($value == $chosen) ? ' checked="checked"' : ''; // Если значение совпадает с выбранным, добавляем атрибут checked
$title = $use_titles ? $titles[$k] : $value; // Определяем заголовок: либо из $titles, либо используем само значение
if (!$htmlspecialcharsBypass) { // Если не указано пропускать htmlspecialchars()
$title = htmlspecialchars($title); // Экранируем заголовок для предотвращения XSS
}
if ($i > 0) { // Если это не первый элемент
$result .= $separator; // Добавляем разделитель
}
$result .= cot_rc( // Генерируем HTML-код для текущего переключателя
$rc, // Используем ресурс для оформления
[
'value' => $htmlspecialcharsBypass ? $value : htmlspecialchars($value), // Значение переключателя
'name' => $name, // Имя переключателя
'checked' => $checked, // Атрибут checked, если элемент выбран
'title' => $title, // Заголовок для переключателя
'attrs' => $input_attrs, // Дополнительные атрибуты
]
);
$i++; // Увеличиваем счётчик
}
return $result; // Возвращаем готовый HTML-код
}
/**
* Генерирует выпадающий список (select)
*
* @param mixed $chosen Выбранное значение (или массив значений для multi-select) // Указывает значение, которое будет выбрано
* @param string $name Имя выпадающего списка // Имя атрибута name для элемента select
* @param array $values Доступные варианты // Массив значений для элементов списка
* @param array $titles Заголовки для вариантов // Массив заголовков, отображаемых для каждого значения
* @param bool $add_empty Разрешить пустой выбор // Добавляет пустой элемент в начало списка
* @param mixed $attrs Дополнительные атрибуты (строка или массив) // Атрибуты для элемента select
* @param string $custom_rc Пользовательский ресурс строки // Кастомное оформление для списка
* @param bool $htmlspecialcharsBypass Пропускать htmlspecialchars() для заголовков и значений // Позволяет передавать необработанные HTML-данные
* @return string Возвращает HTML-код выпадающего списка
*/
function cot_selectbox(
$chosen,
$name,
$values,
$titles = [],
$add_empty = true,
$attrs = '',
$custom_rc = '',
$htmlspecialcharsBypass = false
) {
global $R, $cfg; // Подключаем глобальные переменные ресурсов и конфигурации
if (!is_array($values)) { // Проверяем, является ли $values массивом
$values = explode(',', $values); // Если нет, разбиваем строку на массив по запятым
}
if (!is_array($titles)) { // Проверяем, является ли $titles массивом
$titles = explode(',', $titles); // Если нет, разбиваем строку на массив
}
$msgSeparate = isset($cfg['msg_separate'])? $cfg['msg_separate'] : false; // Проверяем настройку разделения сообщений об ошибках
$use_titles = count($values) == count($titles); // Проверяем, совпадает ли количество значений и заголовков
$input_attrs = cot_rc_attr_string($attrs); // Преобразуем атрибуты в строку для HTML
$chosen = cot_import_buffered($name, $chosen); // Проверяем, не было ли ранее сохранённого значения
$multi = is_array($chosen) && (mb_strpos($input_attrs, 'multiple') !== false); // Определяем, используется ли multi-select
$error = $msgSeparate ? cot_implode_messages($name, 'error') : ''; // Генерируем сообщение об ошибке, если необходимо
$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name; // Извлекаем базовое имя из имени массива
$selected = (is_null($chosen) || $chosen === '' || $chosen == '00') ? ' selected="selected"' : ''; // Если выбранное значение пустое, добавляем атрибут selected
$rc = empty($R["input_option_{$rc_name}"]) ? 'input_option' : "input_option_{$rc_name}"; // Устанавливаем ресурс строки для элемента option
$options = ''; // Инициализируем переменную для хранения опций
if ($add_empty) { // Если разрешён пустой выбор
$options .= cot_rc($rc, array(
'value' => '', // Значение для пустого элемента
'selected' => $selected, // Атрибут selected для пустого элемента
'title' => $R['code_option_empty'] // Заголовок для пустого элемента
));
}
foreach ($values as $k => $x) { // Перебираем массив значений
$x = trim($x); // Удаляем лишние пробелы
$selected = ($multi && in_array($x, $chosen)) || (!$multi && $x == $chosen) ? ' selected="selected"' : ''; // Определяем, является ли элемент выбранным
$title = ($use_titles && !empty($titles[$k])) ? $titles[$k] : $x; // Устанавливаем заголовок для элемента
if (!$htmlspecialcharsBypass) { // Если не пропускаем htmlspecialchars()
$title = htmlspecialchars($title); // Экранируем заголовок
}
$options .= cot_rc($rc, array(
'value' => $htmlspecialcharsBypass ? $x : htmlspecialchars($x), // Значение элемента
'selected' => $selected, // Атрибут selected
'title' => $title // Заголовок элемента
));
}
$rc = empty($R["input_select_{$rc_name}"]) ? (empty($custom_rc) ? 'input_select' : $custom_rc) : "input_select_{$rc_name}"; // Определяем ресурс строки для элемента select
$result = cot_rc($rc, array(
'name' => $name, // Имя элемента select
'attrs' => $input_attrs, // Дополнительные атрибуты
'error' => $error, // Сообщение об ошибке
'options' => $options // Список опций
));
return $result; // Возвращаем HTML-код выпадающего списка
}
/**
* Генерирует выпадающий список с названиями стран
*
* @param string $chosen Выбранное значение // Код выбранной страны
* @param string $name Имя выпадающего списка // Имя атрибута name для элемента select
* @param bool $add_empty Добавить пустой элемент // Добавляет опцию "---" в начало списка
* @param mixed $attrs Дополнительные атрибуты (строка или массив) // Атрибуты для элемента select
* @param string $custom_rc Пользовательский ресурс строки // Кастомное оформление для списка
* @return string Возвращает HTML-код выпадающего списка с названиями стран
*/
function cot_selectbox_countries($chosen, $name, $add_empty = true, $attrs = '', $custom_rc = '')
{
global $cot_countries; // Подключаем глобальную переменную со списком стран
if (!$cot_countries) // Проверяем, инициализирован ли список стран
include_once cot_langfile('countries', 'core'); // Если нет, подключаем файл со списком стран
$codes = array_keys($cot_countries); // Получаем массив кодов стран
$names = array_values($cot_countries); // Получаем массив названий стран
if ($add_empty) // Если нужно добавить пустой элемент
{
array_unshift($codes, '00'); // Добавляем код "00" в начало массива кодов
array_unshift($names, '---'); // Добавляем "---" в начало массива названий
}
// Возвращаем сгенерированный выпадающий список с использованием cot_selectbox
return cot_selectbox($chosen, $name, $codes, $names, false, $attrs, $custom_rc);
}
Пояснения:
$cot_countries— это глобальный массив, где ключи — коды стран (например,US,FR), а значения — их названия (например,United States,France).- Если
$cot_countriesещё не был загружен, используется функцияcot_langfile, которая подключает файлcountries.lang.phpиз директорииcore/langдля инициализации списка. - Функция
cot_selectboxотвечает за создание выпадающего списка. Она получает массив кодов стран и соответствующих названий. - При необходимости в начало списков добавляются элементы для пустого выбора — код
"00"и название"---". - Возвращаемый результат — это готовый HTML-код
<select>с опциями, сформированный на основе ресурсов Cotonti.
/**
* Генерирует выпадающий список для выбора даты и времени
*
* @param int $utime Выбранная временная метка // Таймстамп для предварительного выбора даты и времени
* @param string $mode Режим отображения: 'short' или 'long' // Определяет формат отображения даты
* @param string $name Префикс имени переменной // Имя для атрибутов name выпадающих списков
* @param int $max_year Максимальный год // Верхняя граница диапазона годов
* @param int $min_year Минимальный год // Нижняя граница диапазона годов
* @param bool $usertimezone Использовать временную зону пользователя // Корректирует время относительно часового пояса пользователя
* @param string $custom_rc Пользовательский ресурс строки // Кастомный шаблон для рендеринга
* @return string Возвращает HTML-код выпадающего списка для выбора даты
*/
function cot_selectbox_date($utime, $mode = 'long', $name = '', $max_year = 2030, $min_year = 2000, $usertimezone = true, $custom_rc = '')
{
global $L, $R, $usr; // Глобальные массивы с переводами, ресурсами шаблонов и данными пользователя
if (function_exists('cot_selectbox_date_custom')) // Если существует кастомная функция для генерации даты
{
return cot_selectbox_date_custom($utime, $mode, $name, $max_year, $min_year, $usertimezone, $custom_rc); // Вызываем её
}
$result = NULL; // Переменная для хранения результата
/* === Хук === */
foreach (cot_getextplugins('form.date') as $pl) // Проверяем подключённые плагины
{
include $pl; // Подключаем каждый плагин
}
/* ===== */
if($result !== NULL) return $result; // Если результат определён плагинами, возвращаем его
$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name; // Извлекаем имя ресурса из имени переменной
$utime = ($usertimezone && $utime > 0) ? ($utime + $usr['timezone'] * 3600) : $utime; // Корректируем таймстамп на часовой пояс пользователя
if ($utime == 0) // Если таймстамп равен 0 (дата не выбрана)
{
list($s_year, $s_month, $s_day, $s_hour, $s_minute) = array(null, null, null, null, null); // Устанавливаем пустые значения
$buffered = cot_import_buffered($name, null); // Проверяем наличие буферизованного значения
if (is_array($buffered)) // Если значение является массивом
{
$s_year = $buffered['year']; // Год
$s_month = $buffered['month']; // Месяц
$s_day = $buffered['day']; // День
$s_hour = $buffered['hour'] > 0 ? $buffered['hour'] : 1; // Час (если не указан, то 1)
$s_minute = $buffered['minute']; // Минута
}
}
else // Если таймстамп указан
{
list($s_year, $s_month, $s_day, $s_hour, $s_minute) = explode('-', @date('Y-m-d-H-i', $utime)); // Разбиваем дату на части
}
$months = array(); // Массив для хранения месяцев
$months[1] = $L['January']; // Январь
$months[2] = $L['February']; // Февраль
$months[3] = $L['March']; // Март
$months[4] = $L['April']; // Апрель
$months[5] = $L['May']; // Май
$months[6] = $L['June']; // Июнь
$months[7] = $L['July']; // Июль
$months[8] = $L['August']; // Август
$months[9] = $L['September']; // Сентябрь
$months[10] = $L['October']; // Октябрь
$months[11] = $L['November']; // Ноябрь
$months[12] = $L['December']; // Декабрь
$year = cot_selectbox($s_year, $name.'[year]', range($max_year, $min_year, -1)); // Генерируем выпадающий список для года
$month = cot_selectbox($s_month, $name.'[month]', array_keys($months), array_values($months)); // Для месяца
$day = cot_selectbox($s_day, $name.'[day]', range(1, 31)); // Для дня
$range = array(); // Диапазон для часов
for ($i = 0; $i < 24; $i++) // Заполняем диапазон от 0 до 23
{
$range[] = sprintf('%02d', $i); // Приводим к формату "00"
}
$hour = cot_selectbox($s_hour, $name.'[hour]', $range); // Генерируем список для часов
$range = array(); // Диапазон для минут
for ($i = 0; $i < 60; $i++) // Заполняем диапазон от 0 до 59
{
$range[] = sprintf('%02d', $i); // Приводим к формату "00"
}
$minute = cot_selectbox($s_minute, $name.'[minute]', $range); // Генерируем список для минут
$rc = empty($R["input_date_{$mode}"]) ? 'input_date' : "input_date_{$mode}"; // Выбираем шаблон для отображения даты
$rc = empty($R["input_date_{$rc_name}"]) ? $rc : "input_date_{$rc_name}"; // Проверяем на наличие кастомного шаблона
$rc = empty($custom_rc) ? $rc : $custom_rc; // Если задан пользовательский ресурс, используем его
$result = cot_rc($rc, array( // Формируем результат
'day' => $day, // День
'month' => $month, // Месяц
'year' => $year, // Год
'hour' => $hour, // Часы
'minute' => $minute // Минуты
));
return $result; // Возвращаем результат
}
Пояснение ключевых моментов:
- Поддержка плагинов: Сначала функция проверяет, подключены ли плагины, и позволяет им вмешиваться в процесс генерации даты.
- Коррекция по временной зоне: Если включено использование часовой зоны пользователя, функция корректирует таймстамп.
- Буферизация данных: Поддерживается использование ранее введённых значений (для повторного отображения в форме).
- Многократное использование: Генерация выпадающих списков основана на универсальной функции
cot_selectbox.
/**
* Возвращает выпадающий список для выбора языка
*
* @param string $chosen Выбранное значение // Предварительно выбранный язык
* @param string $name Имя выпадающего списка // Атрибут name для HTML-элемента
* @param bool $add_empty Добавить пустой вариант языка // Опция для добавления пустого значения в начало списка
* @param mixed $attrs Дополнительные атрибуты как ассоциативный массив или строка // Атрибуты для HTML-разметки
* @param string $custom_rc Пользовательский ресурс строки // Кастомный шаблон для рендеринга
* @return string Возвращает HTML-код выпадающего списка для выбора языка
*/
function cot_selectbox_lang($chosen, $name, $add_empty = false, $attrs = '', $custom_rc = '')
{
global $cot_languages, $cot_countries, $cfg; // Глобальные массивы языков, стран и конфигурации
$handle = opendir($cfg['lang_dir'] . '/'); // Открываем директорию с языковыми файлами
while ($f = readdir($handle)) // Перебираем содержимое директории
{
if ($f[0] != '.' && is_dir($cfg['lang_dir'] . '/' . $f)) // Игнорируем скрытые файлы и проверяем, является ли элемент директорией
{
$langlist[] = $f; // Добавляем язык в список
}
}
closedir($handle); // Закрываем директорию
sort($langlist); // Сортируем список языков в алфавитном порядке
if (!$cot_countries) // Если массив стран не загружен
include_once cot_langfile('countries', 'core'); // Подключаем языковой файл с названиями стран
$vals = array(); // Массив для значений (коды языков)
$titles = array(); // Массив для отображаемых названий языков
foreach ($langlist as $lang) // Перебираем список языков
{
$vals[] = $lang; // Добавляем код языка
$titles[] = (empty($cot_languages[$lang]) ? $cot_countries[$lang] : $cot_languages[$lang]) . " ($lang)";
// Формируем отображаемое название языка. Если язык не найден в cot_languages, используем название из cot_countries
}
return cot_selectbox($chosen, $name, $vals, $titles, $add_empty, $attrs, $custom_rc);
// Генерируем выпадающий список, используя универсальную функцию cot_selectbox
}
Пошаговое объяснение:
-
Инициализация директорий языков:
- Сначала открывается папка, указанная в
$cfg['lang_dir']. Это директория, где хранятся языковые файлы. - Цикл
whileперебирает содержимое папки, отбрасывая скрытые файлы (начинающиеся с.) и оставляя только директории (предположительно названия языков).
- Сначала открывается папка, указанная в
-
Сортировка списка языков:
- После перебора директорий, список языков сортируется с помощью функции
sort().
- После перебора директорий, список языков сортируется с помощью функции
-
Проверка и загрузка стран:
- Если массив
$cot_countriesещё не загружен, подключается файл стран из языковых файловcot_langfile('countries', 'core').
- Если массив
-
Формирование списков значений и названий:
- Для каждого языка создаются два массива:
$valsдля хранения кодов языков (например,en,ru).$titlesдля отображения языков, которые формируются следующим образом:- Сначала проверяется, есть ли значение для языка в массиве
$cot_languages. - Если значение отсутствует, берётся название из массива
$cot_countries.
- Сначала проверяется, есть ли значение для языка в массиве
- Для каждого языка создаются два массива:
-
Генерация выпадающего списка:
- Используется универсальная функция
cot_selectboxдля создания HTML-кода выпадающего списка, передавая массивы значений и названий.
- Используется универсальная функция
Результат:
Функция возвращает выпадающий список, который показывает названия доступных языков (например, "Русский (ru)") и позволяет пользователю выбрать один из них.
/**
* Возвращает выпадающий список для выбора часового пояса
*
* @param string $chosen Выбранное значение, должно быть одним из поддерживаемых PHP идентификаторов часового пояса. // Указывает на текущий выбранный часовой пояс
* @param string $name Имя формы // Атрибут name для HTML-элемента
* @param bool $add_gmt Добавить вариант GMT в начало списка // Указывает, нужно ли добавить вариант GMT в выпадающий список
* @param bool $dst Показать смещение с учетом летнего времени, если оно действует // Указывает, учитывать ли летнее время в описаниях
* @param mixed $attrs Дополнительные атрибуты как ассоциативный массив или строка // Дополнительные атрибуты для HTML-разметки
* @param string $custom_rc Пользовательский ресурс строки // Указывает пользовательский шаблон рендеринга
* @return string Возвращает HTML-код выпадающего списка для выбора часового пояса
*/
function cot_selectbox_timezone($chosen, $name, $add_gmt = true, $dst = false, $attrs = '', $custom_rc = '')
{
$timezonelist = cot_timezone_list($add_gmt, $dst); // Получаем список часовых поясов с описаниями
foreach($timezonelist as $timezone) // Перебираем каждый элемент в списке часовых поясов
{
$names[] = $timezone['identifier']; // Сохраняем идентификатор часового пояса (например, 'Europe/Moscow')
$titles[] = $timezone['description']; // Сохраняем описание часового пояса (например, 'UTC+3 - Moscow')
}
return cot_selectbox($chosen, $name, $names, $titles, false, $attrs, $custom_rc);
// Генерируем HTML-код выпадающего списка с использованием функции cot_selectbox
}
Пошаговое объяснение:
-
Список часовых поясов:
- Функция
cot_timezone_listгенерирует массив с доступными часовыми поясами. - Входящие параметры
$add_gmtи$dstопределяют, добавлять ли GMT как отдельный вариант и учитывать ли летнее время в описаниях.
- Функция
-
Формирование массивов значений и названий:
- Цикл
foreachпроходит по каждому элементу массива часовых поясов. identifierиспользуется как значение (например,Europe/Moscow).descriptionиспользуется для отображения текста (например,UTC+3 - Moscow).
- Цикл
-
Генерация выпадающего списка:
- Для создания HTML-кода выпадающего списка вызывается функция
cot_selectbox, которая принимает:$chosen— текущее выбранное значение.$name— имя элемента.$names— массив значений часовых поясов.$titles— массив описаний часовых поясов.$attrs— дополнительные атрибуты для элемента.$custom_rc— пользовательский шаблон ресурса (если требуется).
- Для создания HTML-кода выпадающего списка вызывается функция
Результат:
Функция возвращает готовый HTML-код выпадающего списка, который позволяет пользователю выбрать часовой пояс из списка доступных значений, включая их описание и возможное добавление GMT-опции
/**
* Генерирует выпадающий список категорий структуры
*
* @param string $extension Код расширения (модуля или плагина) // Указывает, для какого расширения строится список категорий
* @param string $check Выбранное значение // Указывает на категорию, которая будет выбрана по умолчанию
* @param string $name Имя выпадающего списка // Атрибут name для HTML-элемента
* @param string $subcat Показать только подкатегории указанной категории // Фильтрует категории по указанной родительской категории
* @param bool $hidePrivate Скрыть приватные категории // Если true, скрывает категории, доступные только админам
* @param bool $isModule TRUE для модулей, FALSE для плагинов // Указывает тип расширения
* @param bool $addEmpty Разрешить пустой выбор // Добавляет пустой вариант в начало списка
* @param mixed $attrs Дополнительные атрибуты как ассоциативный массив или строка // Позволяет задать дополнительные HTML-атрибуты
* @param string $customRC Пользовательский ресурс строки // Указывает на кастомный шаблон рендеринга
* @return string Возвращает HTML-код выпадающего списка
*/
function cot_selectbox_structure(
$extension,
$check,
$name,
$subcat = '',
$hidePrivate = true,
$isModule = true,
$addEmpty = false,
$attrs = '',
$customRC = ''
) {
// Проверяем, существует ли структура для данного расширения
$categories = is_array(Cot::$structure[$extension]) ? Cot::$structure[$extension] : [];
$categoryList = []; // Инициализируем массив для списка категорий
foreach ($categories as $code => $category) { // Перебираем все категории в структуре
// Определяем, отображать ли категорию
$display = ($hidePrivate && $isModule) ? cot_auth($extension, $code, 'W') : true;
if ($display && !empty($subcat) && isset(Cot::$structure[$extension][$subcat])) {
// Проверяем, находится ли текущая категория внутри указанной подкатегории
$mtch = Cot::$structure[$extension][$subcat]['path'] . '.'; // Строим путь родительской категории
$mtchlen = mb_strlen($mtch); // Вычисляем длину пути
$display = (mb_substr($category['path'], 0, $mtchlen) == $mtch || $code === $subcat); // Проверяем, соответствует ли путь категории
}
// Добавляем категорию в список, если она доступна для чтения
if ((!$isModule || cot_auth($extension, $code, 'R')) && $code !== 'all' && $display) {
$categoryList[$code] = $category['tpath']; // Сохраняем код категории и ее отображаемый путь
}
}
/* === Hook === */
foreach (cot_getextplugins('selectBox.structure') as $pl) { // Загружаем хуки для возможности модификации списка категорий
include $pl;
}
/* ===== */
// Генерируем HTML-код выпадающего списка с помощью функции cot_selectbox
return cot_selectbox($check, $name, array_keys($categoryList), array_values($categoryList), $addEmpty, $attrs, $customRC);
}
Объяснение:
-
Инициализация списка категорий:
- Проверяется, существует ли структура для переданного расширения. Если структура недоступна, используется пустой массив.
-
Фильтрация категорий:
- Для каждой категории проверяется:
- Доступность категории для записи, если
$hidePrivateвключён. - Принадлежность к указанной подкатегории, если параметр
$subcatзадан.
- Доступность категории для записи, если
- Для каждой категории проверяется:
-
Авторизация:
- Категория добавляется в список, только если она доступна для чтения (
cot_auth($extension, $code, 'R')).
- Категория добавляется в список, только если она доступна для чтения (
-
Хуки:
- Через плагинный хук
selectBox.structureможно модифицировать список категорий.
- Через плагинный хук
-
Генерация выпадающего списка:
- Список создаётся с помощью функции
cot_selectbox, которая принимает ключи категорий и их отображаемые пути.
- Список создаётся с помощью функции
Результат:
Функция возвращает HTML-код выпадающего списка категорий структуры, поддерживая авторизацию, фильтрацию подкатегорий и расширяемость через хуки.
/**
* Генерирует текстовую область (textarea)
*
* @param string $name Имя текстовой области // Указывает атрибут name для HTML-элемента
* @param string $value Введенное значение // Текст, который будет отображаться внутри текстовой области
* @param int $rows Количество строк // Устанавливает количество видимых строк текстовой области
* @param int $cols Количество столбцов // Устанавливает количество видимых символов в строке
* @param mixed $attrs Дополнительные атрибуты как ассоциативный массив или строка // Позволяет задать дополнительные HTML-атрибуты
* @param string $custom_rc Пользовательский ресурс строки // Указывает кастомный шаблон для рендеринга
* @return string Возвращает HTML-код текстовой области
*
* @todo Не использовать параметры $rows и $cols
*/
function cot_textarea($name, $value, $rows = null, $cols = null, $attrs = '', $custom_rc = '')
{
global $cot_textarea_count, $R, $cfg;
$cot_textarea_count++; // Увеличиваем счётчик текстовых областей
$input_attrs = cot_rc_attr_string($attrs); // Преобразуем дополнительные атрибуты в строку для HTML
$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name; // Проверяем, является ли имя массивом, и извлекаем основную часть имени
$rc = empty($R["input_textarea_{$rc_name}"]) // Если шаблон input_textarea_<имя> не определён
? (empty($custom_rc) ? 'input_textarea' : $custom_rc) // Используем либо общий шаблон, либо указанный кастомный шаблон
: "input_textarea_{$rc_name}"; // Используем найденный шаблон
// Проверяем, разделены ли сообщения об ошибках, и получаем ошибку, связанную с данным полем
$msgSeparate = isset($cfg['msg_separate']) ? $cfg['msg_separate'] : false;
$error = $msgSeparate ? cot_implode_messages($name, 'error') : ''; // Соединяем сообщения об ошибках в строку
$buffered = cot_import_buffered($name, $value); // Проверяем наличие буферизованных данных для данного поля
// Возвращаем HTML-код текстовой области, собранный с помощью шаблона
return cot_rc(
$rc,
[
'name' => $name, // Указываем имя текстовой области
'value' => is_string($buffered) ? htmlspecialchars($buffered) : '', // Если буферизованные данные — строка, экранируем их для HTML
'rows' => $rows, // Указываем количество строк (пока используется, хотя в будущем планируется убрать)
'cols' => $cols, // Указываем количество столбцов (аналогично строкам)
'attrs' => $input_attrs, // Добавляем дополнительные атрибуты
'error' => $error, // Добавляем сообщение об ошибке, если оно есть
]
);
}
Объяснение:
-
Инициализация счётчика:
$cot_textarea_countувеличивается для отслеживания количества текстовых областей, возможно, для уникальности или аналитики.
-
Обработка атрибутов:
- Функция
cot_rc_attr_stringконвертирует массив или строку дополнительных атрибутов в формат, пригодный для вставки в HTML.
- Функция
-
Определение шаблона:
- Шаблон выбирается в порядке приоритета:
input_textarea_<имя>— шаблон для конкретного поля.- Кастомный ресурс строки
$custom_rc, если задан. - Общий шаблон
input_textarea, если кастомный ресурс не указан.
- Шаблон выбирается в порядке приоритета:
-
Буферизация значений:
cot_import_bufferedпроверяет, было ли значение введено ранее (например, при ошибке валидации) и заменяет текущее значение буферизованным.
-
Обработка ошибок:
- Если для конфигурации установлена опция
$cfg['msg_separate'], ошибки собираются с использованиемcot_implode_messages.
- Если для конфигурации установлена опция
-
Рендеринг HTML:
- Возвращается HTML-код текстовой области, собранный на основе шаблона
cot_rc.
- Возвращается HTML-код текстовой области, собранный на основе шаблона
Результат:
Функция генерирует текстовую область с учётом буферизованных данных, возможных ошибок и дополнительных атрибутов. Она поддерживает кастомизацию через шаблоны и предоставляет гибкость для разных случаев использования.
/**
* Генерирует вывод чеклистбокса (списка чекбоксов)
*
* @param mixed $chosen Состояние выбранных чекбоксов // Выбранные значения, могут быть массивом или строкой
* @param string $name Имя входного элемента // Атрибут name для каждого чекбокса
* @param array $values Доступные значения // Массив значений для чекбоксов
* @param array $titles Заголовки для значений // Массив подписей для значений (опционально)
* @param mixed $attrs Дополнительные атрибуты // Ассоциативный массив или строка для дополнительных HTML-атрибутов
* @param string $separator Разделитель между элементами // По умолчанию берётся из $R['input_radio_separator']
* @param bool $addnull Добавить скрытое поле null для проверки наличия чеклистбокса в форме // Помогает проверить, был ли чеклистбокс отправлен
* @param string $custom_rc Кастомный шаблон ресурса // Позволяет использовать пользовательский шаблон
* @return string Возвращает HTML-код чеклистбокса
*/
function cot_checklistbox($chosen, $name, $values, $titles = array(), $attrs = '', $separator = '', $addnull = true, $custom_rc = '')
{
global $R;
// Если $values не является массивом, преобразуем его в массив, разбивая по запятым
if (!is_array($values))
{
$values = explode(',', $values); // Преобразуем строку в массив значений
}
// Аналогично преобразуем $titles, если он не массив
if (!is_array($titles))
{
$titles = explode(',', $titles); // Преобразуем строку в массив заголовков
}
// Проверяем, равны ли размеры массивов $values и $titles
$use_titles = count($values) == count($titles); // Устанавливаем флаг использования заголовков
// Преобразуем дополнительные атрибуты в строку для HTML
$input_attrs = cot_rc_attr_string($attrs);
// Проверяем, есть ли буферизованные данные для данного имени (восстанавливаем выбранные значения)
$chosen = cot_import_buffered($name, $chosen);
// Если разделитель не указан, берём его из ресурсов
if (empty($separator))
{
$separator = $R['input_radio_separator']; // Используем стандартный разделитель
}
$i = 0; // Счётчик элементов
$result = ''; // Результирующая строка с HTML-кодом
// Если требуется добавить null-поле, создаём скрытый input
if ($addnull)
{
$result .= cot_inputbox('hidden', $name.'[nullval]', 'nullval'); // Скрытое поле для проверки
}
// Определяем имя шаблона для чекбокса
$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name;
// Устанавливаем шаблон ресурса (по умолчанию используем 'input_check')
$rc = empty($R["input_check_{$rc_name}"])
? (empty($custom_rc) ? 'input_check' : $custom_rc)
: "input_check_{$rc_name}";
// Обрабатываем каждое значение из $values
foreach ($values as $k => $x)
{
$i++; // Увеличиваем счётчик
$x = trim($x); // Убираем лишние пробелы вокруг значения
// Проверяем, выбрано ли значение
$checked = (is_array($chosen) && in_array($x, $chosen)) || (!is_array($chosen) && $x == $chosen)
? ' checked="checked"' // Если значение выбрано, добавляем атрибут checked
: '';
// Определяем заголовок для чекбокса
$title = $use_titles ? htmlspecialchars($titles[$k]) : htmlspecialchars($x); // Используем заголовки, если они есть
// Если это не первый элемент, добавляем разделитель
if ($i > 1)
{
$result .= $separator; // Добавляем разделитель между элементами
}
// Добавляем HTML-код чекбокса, используя шаблон
$result .= cot_rc($rc, array(
'value' => htmlspecialchars($x), // Указываем значение чекбокса
'name' => $name.'['.$i.']', // Формируем имя с индексом
'checked' => $checked, // Устанавливаем атрибут checked, если значение выбрано
'title' => $title, // Заголовок для чекбокса
'attrs' => $input_attrs // Дополнительные атрибуты
));
}
// Возвращаем итоговый HTML-код чеклистбокса
return $result;
}
Объяснение кода:
-
Обработка входных данных:
- Если
$valuesи$titlesне массивы, они преобразуются в массивы, разделяя строку по запятым. - Проверяется, совпадает ли количество элементов в
$valuesи$titles.
- Если
-
Формирование шаблона:
- Определяется шаблон ресурса для чекбоксов (
input_checkили кастомный шаблон).
- Определяется шаблон ресурса для чекбоксов (
-
Обработка каждого значения:
- Для каждого значения из
$valuesсоздаётся HTML-код чекбокса. - Проверяется, выбрано ли значение, чтобы добавить атрибут
checked.
- Для каждого значения из
-
Добавление разделителя:
- Между чекбоксами вставляется разделитель, если он указан.
-
Добавление скрытого поля:
- Если
$addnullравноtrue, добавляется скрытое поле для проверки отправки формы.
- Если
-
Возвращение результата:
- Генерируется и возвращается итоговый HTML-код.
/**
* Генерирует поле формы для загрузки файла из строки ресурса
*
* @param string $name Имя входного элемента // Атрибут name для поля
* @param string $value Введённое значение // Значение поля (если файл уже выбран)
* @param string $filepath Путь к файлу, если отличается от значения // Путь к файлу
* @param string $delname Имя чекбокса для удаления файла // Имя чекбокса, который будет использоваться для удаления файла
* @param mixed $attrs Дополнительные атрибуты // Ассоциативный массив или строка для дополнительных HTML-атрибутов
* @param string $custom_rc Кастомное имя строки ресурса // Позволяет использовать пользовательский шаблон
* @return string Возвращает HTML-код поля формы для загрузки файла
*/
function cot_filebox($name, $value = '', $filepath = '', $delname ='', $attrs = '', $custom_rc = '')
{
global $R, $cfg;
// Преобразуем дополнительные атрибуты в строку для HTML
$input_attrs = cot_rc_attr_string($attrs);
// Извлекаем имя из строки $name (если оно выглядит как массив)
$rc_name = preg_match('#^(\w+)\[(.*?)\]$#', $name, $mt) ? $mt[1] : $name;
// Разделяем custom_rc по символу | на два значения
$custom_rc = explode('|', $custom_rc, 2);
// Если значение пустое, выбираем шаблон для пустого файла
if(empty($value))
{
$rc = empty($R["input_filebox_{$rc_name}_empty"])
? (empty($custom_rc[1]) ? 'input_filebox_empty' : $custom_rc[1])
: "input_filebox_{$rc_name}_empty";
}
else
{
// Если значение не пустое, выбираем шаблон для загруженного файла
$rc = empty($R["input_filebox_{$rc_name}"])
? (empty($custom_rc[0]) ? 'input_filebox' : $custom_rc[0])
: "input_filebox_{$rc_name}";
}
// Если путь к файлу пустой, используем значение в качестве пути
$filepath = empty($filepath) ? $value : $filepath;
// Если имя для удаления пустое, генерируем его автоматически
$delname = empty($delname) ? 'del'.$name : $delname;
// Проверка на необходимость отдельного отображения сообщений
$msgSeparate = isset($cfg['msg_separate']) ? $cfg['msg_separate'] : false;
// Собираем сообщения об ошибках, если они есть
$error = $msgSeparate ? cot_implode_messages($name, 'error') : '';
// Возвращаем результат с использованием шаблона для поля загрузки файла
return cot_rc($rc, array(
'name' => $name, // Имя поля
'filepath' => $filepath, // Путь к файлу
'delname' => $delname, // Имя чекбокса для удаления
'value' => $value, // Введённое значение
'attrs' => $input_attrs, // Дополнительные атрибуты
'error' => $error // Ошибки, если они есть
));
}
Объяснение кода:
-
Преобразование атрибутов:
- Атрибуты, переданные через
$attrs, преобразуются в строку для использования в HTML-коде.
- Атрибуты, переданные через
-
Определение имени ресурса:
- Если
$nameвыглядит как массив (например,name[xxx]), то извлекается имя массива.
- Если
-
Выбор шаблона для отображения:
- В зависимости от того, пустое ли значение
$value, выбирается один из двух шаблонов для поля загрузки файла — для пустого или для загруженного файла. Шаблон может быть кастомизирован через параметр$custom_rc.
- В зависимости от того, пустое ли значение
-
Обработка пути к файлу:
- Если
$filepathне задан, используется значение из$valueкак путь к файлу.
- Если
-
Управление именем для удаления файла:
- Если
$delnameне указано, создаётся имя для чекбокса, который будет использоваться для удаления файла.
- Если
-
Обработка ошибок:
- Если существует настройка для отображения сообщений об ошибках (
msg_separate), ошибки собираются и передаются в результат.
- Если существует настройка для отображения сообщений об ошибках (
-
Возврат результата:
- Генерируется и возвращается HTML-код поля загрузки файла с атрибутами и возможными ошибками.
Комментарии (0)
Автор контента
Оффлайн
Administrator
Последняя авторизация: 05.07.2026 18:32
- Страница размещена: 24.01.2025 14:51
- Последнее обновление: 24.01.2025 14:59