Модуль "Users", - users.edit.php в Cotonti CMF
предназначен для обработки запросов на редактирование профиля пользователя, а также для отображения формы редактирования с возможностью изменения различных данных пользователя
Файл "users.edit.php", расположенный в директории "/modules/users/inc", является частью модуля "users" в системе Cotonti CMF. Этот файл предназначен для обработки запросов на редактирование профиля пользователя, а также для отображения формы редактирования с возможностью изменения различных данных пользователя, таких как имя, почта, дата рождения и другие настройки. Этот файл играет ключевую роль в администрировании пользователей на сайте, позволяя модераторам и администраторам изменять данные пользователей через веб-интерфейс.
Основное назначение:
Основная цель файла — обработка и вывод формы редактирования профиля пользователя. Он выполняет следующие задачи:
- Загружает и обрабатывает данные о пользователе.
- Отображает данные пользователя в форме редактирования.
- Обрабатывает изменения, внесенные пользователем.
- Обрабатывает и выводит сообщения об ошибках и успешных действиях.
- Взаимодействует с базой данных для получения и обновления информации о пользователе.
Взаимодействие с сайтом:
Файл работает с несколькими компонентами Cotonti CMF:
- Модуль "users" — взаимодействует с основным функционалом управления пользователями.
- Шаблоны — файл генерирует данные, которые затем передаются в шаблон для отображения пользователю.
- База данных — извлекает информацию о пользователе, а также записывает изменения в профиль.
- Плагины — возможность использования расширений через хуки для добавления дополнительных функций (например, поля).
Переменные, методы, функции, классы:
- Cot::$cfg — глобальная конфигурация сайта.
- Cot::$out — глобальный объект для вывода данных на страницу, например, для задания заголовков.
- Cot::$R — массив с ресурсами, такими как стили и скрипты.
- $urr — переменная, содержащая информацию о пользователе, полученную из базы данных.
- $usersHelper — объект для работы с пользовательскими данными (например, для формирования полного имени пользователя).
- cot_url() — функция для создания URL с учетом маршрутов.
- cot_inputbox() — создание поля ввода в форме.
- cot_selectbox_*() — функции для генерации выпадающих списков (например, для выбора языка, страны, темы).
- cot_radiobox() — функция для создания радиокнопок (например, для выбора, скрывать ли email).
- cot_textarea() — создание поля для ввода многострочного текста.
- cot_build_group() — создание информации о группе пользователя.
- cot_display_messages() — функция для отображения сообщений (например, об ошибках).
- cot_getextplugins() — загрузка плагинов, если они подключены.
- XTemplate — класс для работы с шаблонами в Cotonti.
- UsersHelper::getInstance() — создание или получение экземпляра класса для работы с пользователями.
Суть содержания кода:
- Обработка запроса: Файл начинается с получения данных о пользователе из базы данных на основе его ID.
- Подготовка данных для отображения: Данные о пользователе подготавливаются в массивы и передаются в шаблон.
- Генерация HTML-формы: Для каждого поля редактируемого профиля создается HTML-форма.
- Обработка изменений: После изменения данных, форма отправляется на сервер, и соответствующие данные обновляются в базе.
- Отображение сообщений: В случае успеха или ошибки выводятся соответствующие сообщения.
Как использовать владельцу сайта:
Владельцу сайта необходимо подключить этот файл через интерфейс администрирования. Это обеспечит возможность редактирования данных пользователей через административную панель. Код предоставляет возможность настраивать профили пользователей с множеством опций (например, изменение пароля, темы, языка, полей профиля и т.д.).
Стиль написания и совместимость с PHP:
Код написан с соблюдением основных принципов ООП (например, использование объектов и методов), а также поддерживает работу с массивами и стандартными функциями PHP. Он совместим с современными версиями PHP (PHP 7 и выше), поскольку использует такие конструкции, как массивы, объекты и функции, которые поддерживаются начиная с PHP 5.4.
Файл следует стандартам кода для системы Cotonti, включая использование классов и функций Cotonti для работы с данными и выводом информации.
/**
* Edit User Profile
*
* @package Users
* @copyright (c) Cotonti Team
* @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
*/
use cot\users\UsersHelper; // Подключение класса UsersHelper для работы с данными пользователей
defined('COT_CODE') or die('Wrong URL'); // Проверка, что файл вызывается внутри движка Cotonti, если нет — прекращение выполнения скрипта
require_once cot_incfile('auth'); // Подключение файла с функционалом авторизации пользователей
$y = cot_import('y','P','TXT'); // Получение параметра 'y' из POST-запроса, тип данных — текст (TXT)
$id = (int) cot_import('id','G','INT'); // Получение параметра 'id' из GET-запроса, тип данных — целое число (INT), присваиваем переменной $id
$s = cot_import('s','G','ALP',13); // Получение параметра 's' из GET-запроса, тип данных — строка из алфавитных символов (ALP), длина до 13 символов
$w = cot_import('w','G','ALP',4); // Получение параметра 'w' из GET-запроса, тип данных — строка из алфавитных символов (ALP), длина до 4 символов
$d = cot_import('d','G','INT'); // Получение параметра 'd' из GET-запроса, тип данных — целое число (INT)
$f = cot_import('f','G','TXT'); // Получение параметра 'f' из GET-запроса, тип данных — текст (TXT)
$g = cot_import('g','G','INT'); // Получение параметра 'g' из GET-запроса, тип данных — целое число (INT)
list(Cot::$usr['auth_read'], Cot::$usr['auth_write'], Cot::$usr['isadmin']) = cot_auth('users', 'a'); // Получение прав доступа пользователя для модуля 'users' (чтение, запись, админ) и присваивание их переменным
cot_block(Cot::$usr['isadmin']); // Проверка прав администратора (если не администратор, выполнение кода будет остановлено)
require_once cot_langfile('users', 'module'); // Подключение языкового файла для модуля пользователей
/* === Hook === */
foreach (cot_getextplugins('users.edit.first') as $pl) { // Запуск плагинов, зарегистрированных для хука 'users.edit.first'
include $pl; // Подключение каждого плагина, найденного для хука
}
/* ===== */
cot_die(empty($id), true); // Прекращение выполнения, если параметр 'id' пуст, вывод ошибки
$sql = Cot::$db->query("SELECT * FROM $db_users WHERE user_id = ?", $id); // Выполнение SQL-запроса для получения данных пользователя по его ID
cot_die($sql->rowCount()==0, true); // Прекращение выполнения, если пользователь с таким ID не найден, вывод ошибки
$urr = $sql->fetch(); // Извлечение данных пользователя из результата запроса и присваивание их переменной $urr
$sql1 = Cot::$db->query("SELECT gru_groupid FROM $db_groups_users WHERE gru_userid=$id and gru_groupid=".COT_GROUP_SUPERADMINS); // Выполнение SQL-запроса для проверки, состоит ли пользователь в группе супер-администраторов
$sys['edited_istopadmin'] = ($sql1->rowCount()>0) ? TRUE : FALSE; // Проверка, если пользователь является супер-администратором, и присваивание результата в переменную $sys['edited_istopadmin']
$sys['user_istopadmin'] = cot_auth('admin', 'a', 'A'); // Проверка, имеет ли текущий пользователь права супер-администратора
$sys['protecttopadmin'] = $sys['edited_istopadmin'] && !$sys['user_istopadmin']; // Если редактируемый пользователь является супер-администратором, а текущий пользователь — нет, включаем защиту
if ($sys['protecttopadmin']) { // Если защита от редактирования супер-администратора включена
cot_die_message(930, TRUE); // Завершаем выполнение с сообщением об ошибке (код 930), пользователь не может редактировать супер-администратора
}
if ($a == 'update') { // Если действие 'update', то продолжаем обработку
cot_check_xg(); // Проверка на корректность CSRF-токена для безопасности
/* === Hook === */
foreach (cot_getextplugins('users.edit.update.first') as $pl) { // Пробегаем по всем подключённым плагинам, активированным для хука 'users.edit.update.first'
include $pl; // Подключаем каждый плагин, если он существует
}
/* ===== */
$ruserdelete = cot_import('ruserdelete','P','BOL'); // Получаем параметр 'ruserdelete' из POST-запроса, тип данных - булев (проверка на удаление пользователя)
if ($ruserdelete) { // Если был выбран параметр для удаления пользователя
Cot::$db->delete($db_users, "user_id=$id"); // Удаляем пользователя из основной таблицы пользователей
Cot::$db->delete($db_groups_users, "gru_userid=$id"); // Удаляем записи о пользователе из таблицы групп пользователей
foreach($cot_extrafields[$db_users] as $exfld) { // Пробегаем все дополнительные поля пользователей
cot_extrafield_unlinkfiles($urr['user_'.$exfld['field_name']], $exfld); // Удаляем файлы, связанные с пользовательскими дополнительными полями
}
if (cot_module_active('pfs') && cot_import('ruserdelpfs','P','BOL')) { // Если активирован модуль pfs и был запрашиваем параметр для удаления файлов из pfs
require_once cot_incfile('pfs', 'module'); // Подключаем файл модуля pfs
cot_pfs_deleteall($id); // Удаляем все файлы, связанные с пользователем из pfs
}
/* === Hook === */
foreach (cot_getextplugins('users.edit.update.delete') as $pl) { // Обрабатываем хук для плагинов, связанных с удалением пользователя
include $pl; // Подключаем и выполняем каждый плагин
}
/* ===== */
cot_log("Deleted user #".$id, 'users', 'delete', 'done'); // Логируем событие удаления пользователя
cot_redirect(cot_url('message', "msg=109&rc=200&id=".$id, '', true)); // Перенаправляем на страницу с сообщением об успешном удалении
}
Пояснение: Этот фрагмент кода реализует удаление пользователя. Если флаг $ruserdelete установлен (например, через форму), то происходит:
- Удаление записи о пользователе из базы данных.
- Удаление информации о его группах.
- Удаление файлов, связанных с пользовательскими дополнительными полями.
- При наличии модуля pfs (Personal File Storage) и установленном флаге для удаления файлов, происходит удаление всех файлов пользователя из pfs.
- Если есть подключённые плагины для хука 'users.edit.update.delete', они обрабатываются.
- Логируется факт удаления пользователя, и происходит редирект на страницу с сообщением об успешном удалении.
$ruser['user_name'] = cot_import('rusername','P','TXT'); // Получаем имя пользователя из POST-запроса, тип данных - строка (TEXT)
$ruser['user_maingrp'] = cot_import('rusermaingrp','P','INT'); // Получаем основной идентификатор группы пользователя из POST-запроса, тип данных - целое число (INT)
$ruser['user_banexpire'] = cot_import('ruserbanexpire','P','INT'); // Получаем дату истечения бана пользователя из POST-запроса, тип данных - целое число (INT)
$ruser['user_country'] = cot_import('rusercountry','P','ALP'); // Получаем страну пользователя из POST-запроса, тип данных - строка с буквами (ALP)
$ruser['user_text'] = cot_import('rusertext','P','HTM'); // Получаем текстовое описание пользователя из POST-запроса, тип данных - HTML
$rtheme = cot_import('rusertheme','P','TXT'); // Получаем строку с темой пользователя из POST-запроса, тип данных - строка (TXT)
$rtheme = !empty($rtheme) ? explode(':', $rtheme) : []; // Разделяем строку темы по двоеточию, если строка не пуста
$ruser['user_theme'] = $rtheme[0]; // Сохраняем первую часть разделённой строки как тему пользователя
$ruser['user_scheme'] = $rtheme[1]; // Сохраняем вторую часть разделённой строки как схему оформления пользователя
$ruser['user_email'] = cot_import('ruseremail','P','TXT'); // Получаем email пользователя из POST-запроса, тип данных - строка (TXT)
$ruser['user_hideemail'] = cot_import('ruserhideemail','P','INT'); // Получаем флаг скрытия email пользователя из POST-запроса, тип данных - целое число (INT)
$ruser['user_lang'] = cot_import('ruserlang','P','ALP'); // Получаем язык пользователя из POST-запроса, тип данных - строка с буквами (ALP)
$ruser['user_gender'] = cot_import('rusergender','P','TXT'); // Получаем пол пользователя из POST-запроса, тип данных - строка (TXT)
Пояснение: Этот участок кода обрабатывает входящие данные из POST-запроса, относящиеся к профилю пользователя. Для каждого поля происходит импорт и фильтрация данных:
- Имя пользователя, группа, email, пол, страна и другие данные импортируются через функцию
cot_import(), которая очищает и проверяет тип данных (например, строки, числа, HTML). - В строке с темой (
ruser.theme) выполняется разбиение на две части (например, тему и схему оформления), которые затем сохраняются в массиве$ruser. - Полученные данные сохраняются в ассоциативном массиве
$ruser, который будет использоваться далее в коде для обновления информации о пользователе.
$ruser['user_birthdate'] = cot_import_date('ruserbirthdate', false); // Получаем дату рождения пользователя из POST-запроса с помощью функции cot_import_date(). Если дата не указана, будет возвращено значение null.
if (!is_null($ruser['user_birthdate']) && $ruser['user_birthdate'] > Cot::$sys['now']) { // Проверяем, что дата рождения не пустая и не больше текущей даты
cot_error('pro_invalidbirthdate', 'ruserbirthdate'); // Если дата рождения некорректная (больше текущей даты), генерируем ошибку с кодом 'pro_invalidbirthdate'.
}
$ruser['user_timezone'] = cot_import('rusertimezone','P','TXT'); // Получаем временную зону пользователя из POST-запроса, тип данных - строка (TXT)
$rusernewpass = (string) cot_import('rusernewpass','P','NOC', 32); // Получаем новый пароль пользователя из POST-запроса, тип данных - строка (NOC), ограничиваем длину до 32 символов
Пояснение:
- В первом блоке проверяется дата рождения пользователя. Если она указана, но больше текущей даты, генерируется ошибка, сообщающая о некорректности введенной даты.
- Во втором блоке из POST-запроса получаем временную зону и новый пароль пользователя. Данные сохраняются в массиве
$ruserдля последующего использования.- Для пароля используется фильтр
NOCс ограничением длины в 32 символа, что предотвращает атаки через слишком длинные строки. - Также временная зона сохраняется в строковом формате.
- Для пароля используется фильтр
// Extra fields
if (!empty(Cot::$extrafields[Cot::$db->users])) { // Проверяем, существуют ли дополнительные поля для пользователей
foreach (Cot::$extrafields[Cot::$db->users] as $exfld) { // Проходим по всем дополнительным полям для пользователей
$ruser['user_' . $exfld['field_name']] = cot_import_extrafields('ruser' . $exfld['field_name'], $exfld, 'P', // Импортируем значения дополнительных полей пользователя из POST-запроса
$urr['user_' . $exfld['field_name']], 'user_'); // Используем текущие значения из базы данных в качестве значений по умолчанию для дополнительных полей
}
}
Пояснение:
- Проверяется наличие дополнительных полей (extrafields) для пользователей в глобальном массиве
Cot::$extrafieldsдля текущей таблицы пользователей (Cot::$db->users). - Если такие поля существуют, они обрабатываются через цикл
foreach. Для каждого поля выполняется импорт данных из POST-запроса с использованием функцииcot_import_extrafields(). - При этом для каждого дополнительного поля используется его текущее значение в базе данных как значение по умолчанию, если оно не было передано в запросе. Это позволяет корректно обновлять поля пользователя без потери данных.
$rusergroupsms = cot_import('rusergroupsms', 'P', 'ARR'); // Импортируем список групп сообщений для пользователя из POST-запроса (массив)
// Проверка имени пользователя
if (mb_strlen($ruser['user_name']) < 2 || mb_strpos($ruser['user_name'], ',') !== false || mb_strpos($ruser['user_name'], "'") !== false) { // Проверяем, что имя пользователя не слишком короткое (менее 2 символов) и не содержит недопустимые символы (запятая или апостроф)
cot_error('aut_usernametooshort', 'rusername'); // Если имя пользователя не соответствует условиям, генерируем ошибку
}
// Проверка уникальности имени пользователя
if ($ruser['user_name'] != $urr['user_name'] && Cot::$db->query("SELECT COUNT(*) FROM ".Cot::$db->users." WHERE user_name = ?", // Если имя пользователя изменяется, проверяем, не существует ли уже такое имя в базе данных
array($ruser['user_name']))->fetchColumn() > 0) { // Запрос на проверку наличия такого имени в базе
cot_error('aut_usernamealreadyindb', 'rusername'); // Если имя уже существует в базе, генерируем ошибку
}
Пояснение:
- Первая строка импортирует массив
rusergroupsms, который содержит группы сообщений для пользователя из POST-запроса. - Далее идет проверка:
- Имя пользователя должно быть не менее двух символов и не содержать запятых или апострофов. Если одно из этих условий нарушено, вызывается ошибка с сообщением "Имя пользователя слишком короткое" или с указанием на недопустимые символы.
- Затем проверяется, изменяется ли имя пользователя и если да, то делается запрос к базе данных для проверки уникальности нового имени пользователя. Если в базе уже есть такое имя, вызывается ошибка "Имя пользователя уже существует".
if (!cot_check_email($ruser['user_email'])) // Проверяем, что введенный email имеет правильный формат
{
cot_error('aut_emailtooshort', 'ruseremail'); // Если email некорректен, генерируем ошибку с сообщением о неправильном формате email
}
if ($ruser['user_email'] != $urr['user_email'] && Cot::$db->query("SELECT COUNT(*) FROM ".Cot::$db->users." WHERE user_email = ?", // Если email был изменен, проверяем, не существует ли уже такой email в базе данных
array($ruser['user_email']))->fetchColumn() > 0) // Запрос на проверку существования такого email в базе
{
cot_error('aut_emailalreadyindb', 'ruseremail'); // Если email уже существует в базе, генерируем ошибку с сообщением "Email уже зарегистрирован"
}
if (!empty($rusernewpass) && mb_strlen($rusernewpass) < 4) // Проверяем, что новый пароль введен и его длина не менее 4 символов
{
cot_error('aut_passwordtooshort', 'rusernewpass'); // Если пароль слишком короткий, генерируем ошибку с сообщением "Пароль слишком короткий"
}
Пояснение:
- Первая проверка касается email:
- Функция
cot_check_email()проверяет, что введенный email имеет правильный формат. Если email некорректен, вызывается ошибка с сообщением "Email слишком короткий" (что является стандартным сообщением для всех неверных форматов email в системе).
- Функция
- Вторая проверка проверяет уникальность email:
- Если email был изменен, выполняется запрос к базе данных для проверки, не занят ли этот email уже другим пользователем. Если такой email найден, выводится ошибка с сообщением "Email уже существует в базе".
- Третья проверка проверяет новый пароль:
- Если новый пароль введен, но его длина меньше 4 символов, генерируется ошибка с сообщением "Пароль слишком короткий".
if (!cot_error_found()) // Если ошибок не найдено
{
if (!empty($rusernewpass)) // Если новый пароль был введен
{
$ruser['user_passsalt'] = cot_unique(16); // Генерируем уникальную соль для пароля
$ruser['user_passfunc'] = empty($cfg['hashfunc']) ? 'sha256' : $cfg['hashfunc']; // Выбираем хеш-функцию, по умолчанию sha256
$ruser['user_password'] = cot_hash($rusernewpass, $ruser['user_passsalt'], $ruser['user_passfunc']); // Хешируем пароль с солью
}
$ruser['user_name'] = ($ruser['user_name'] == '') ? $urr['user_name'] : $ruser['user_name']; // Если имя не изменено, оставляем старое имя
// Обработка даты рождения
if (is_null($ruser['user_birthdate'])) // Если дата рождения не задана
{
if (isset($_POST['ruserbirthdate'])) // Если дата рождения была удалена в форме
{
$ruser['user_birthdate'] = 'NULL'; // Устанавливаем NULL для даты рождения
} else {
unset($ruser['user_birthdate']); // Убираем дату рождения, если она не задана
}
} else {
$ruser['user_birthdate'] = cot_stamp2date($ruser['user_birthdate']); // Преобразуем метку времени в формат даты
}
// Если имя пользователя изменилось, обновляем данные в других модулях
if ($ruser['user_name'] != $urr['user_name']) {
$newname = $ruser['user_name']; // Новое имя пользователя
$oldname = $urr['user_name']; // Старое имя пользователя
// Обновляем имя пользователя в различных модулях, если они активированы
if (cot_module_active('forums'))
{
require_once cot_incfile('forums', 'module'); // Подключаем модуль форумов
$db->update($db_forum_topics, array('ft_lastpostername' => $newname), 'ft_lastpostername = ?', array($oldname)); // Обновляем имя последнего автора в темах форума
$db->update($db_forum_topics, array('ft_firstpostername' => $newname), 'ft_firstpostername = ?', array($oldname)); // Обновляем имя первого автора в темах форума
$db->update($db_forum_posts, array('fp_postername' => $newname), 'fp_postername = ?', array($oldname)); // Обновляем имя автора в сообщениях форума
$db->update($db_forum_stats, array('fs_lt_postername' => $newname), 'fs_lt_postername = ?', array($oldname)); // Обновляем имя последнего автора в статистике форума
if (!empty(Cot::$cache)) {
Cot::$cache->db->remove('cot_sections_act', 'system'); // Очистка кэша секций
}
}
if (cot_module_active('page'))
{
require_once cot_incfile('page', 'module'); // Подключаем модуль страниц
$db->update($db_pages, array('page_author' => $newname), 'page_author = ?', array($oldname)); // Обновляем имя автора страниц
}
if (cot_plugin_active('comments'))
{
require_once cot_incfile('comments', 'plug'); // Подключаем плагин комментариев
$db->update($db_com, array('com_author' => $newname), 'com_author = ?', array($oldname)); // Обновляем имя автора комментариев
}
if (cot_module_active('pm'))
{
require_once cot_incfile('pm', 'module'); // Подключаем модуль личных сообщений
$db->update($db_pm, array('pm_fromuser' => $newname), 'pm_fromuser = ?', array($oldname)); // Обновляем имя отправителя в личных сообщениях
}
if (cot_plugin_active('whosonline'))
{
$db->update($db_online, array('online_name' => $newname), 'online_name = ?', array($oldname)); // Обновляем имя пользователя в списке онлайн
}
}
$ruser['user_auth'] = ''; // Очищаем поле аутентификации пользователя
$sql = $db->update($db_users, $ruser, 'user_id=' . $id); // Обновляем информацию о пользователе в базе данных
cot_extrafield_movefiles(); // Перемещаем файлы экстраполя (если они есть)
// Проверка и установка основной группы пользователя
$ruser['user_maingrp'] = ($ruser['user_maingrp'] < COT_GROUP_MEMBERS && $id == 1) ? COT_GROUP_SUPERADMINS : $ruser['user_maingrp']; // Если это суперпользователь, устанавливаем группу суперадминистратора
if (!$rusergroupsms[$ruser['user_maingrp']])
{
$rusergroupsms[$ruser['user_maingrp']] = 1; // Устанавливаем флаг для основной группы
}
$db->update($db_users, array('user_maingrp' => $ruser['user_maingrp']), 'user_id=' . $id); // Обновляем основную группу пользователя
// Обновляем группы пользователя в таблице групп
foreach ($cot_groups as $k => $i)
{
if (isset($rusergroupsms[$k])) // Если группа активирована
{
if ($db->query("SELECT gru_userid FROM $db_groups_users WHERE gru_userid=$id AND gru_groupid=$k")->rowCount() == 0
&& !($id == 1 && in_array($k, array(COT_GROUP_BANNED, COT_GROUP_INACTIVE)))) // Проверка на существование записи о пользователе в группе
{
$db->insert($db_groups_users, array('gru_userid' => (int)$id, 'gru_groupid' => (int)$k)); // Добавляем пользователя в группу
}
}
else
{
$db->delete($db_groups_users, "gru_userid=$id AND gru_groupid=$k"); // Удаляем пользователя из группы
}
}
// Если пользователь активировал свою учетную запись, отправляем уведомление по email
if ($ruser['user_maingrp'] == COT_GROUP_MEMBERS && $urr['user_maingrp'] == COT_GROUP_INACTIVE) {
$rsubject = Cot::$L['useed_accountactivated']; // Тема письма
$rbody = Cot::$L['Hi'] . " " . $urr['user_name'] . ",\n\n"; // Текст письма
$rbody .= Cot::$L['useed_email'];
$rbody .= "\n\n" . Cot::$L['aut_contactadmin'];
cot_mail($urr['user_email'], $rsubject, $rbody); // Отправка email
}
/* === Hook === */
foreach (cot_getextplugins('users.edit.update.done') as $pl) {
include $pl; // Выполнение хуков, если есть
}
/* ===== */
cot_auth_clear($id); // Очищаем кэш авторизации для пользователя
cot_log("Edited user #".$id, 'users', 'edit', 'done'); // Логируем изменение пользователя
cot_message('User_data_updated'); // Сообщение об успешном обновлении данных пользователя
cot_redirect(cot_url('users', "m=edit&id=" . $id, '', true)); // Перенаправление на страницу редактирования пользователя
}
else
{
cot_redirect(cot_url('users', "m=edit&id=$id", '', true)); // Перенаправление, если были ошибки
}
Здесь происходит процесс обновления данных пользователя в системе. Вот основные шаги, которые выполняются:
-
Проверка на наличие ошибок: Сначала проверяется, были ли найдены ошибки. Если ошибок нет, продолжаем обновление.
-
Обработка пароля: Если был введен новый пароль, генерируется соль и выбирается хеш-функция для пароля. Пароль хешируется с использованием этой соли и функции.
-
Обработка имени пользователя: Если имя пользователя изменилось, оно обновляется в базе данных и проверяется, нужно ли обновить имя пользователя в других модулях системы, таких как форумы, страницы, комментарии и личные сообщения.
-
Обработка даты рождения: Если дата рождения была удалена, она устанавливается как
NULL. В противном случае, она преобразуется в формат даты. -
Обновление данных пользователя: Все изменения (например, пароль, имя пользователя, дата рождения) сохраняются в базе данных.
-
Обновление группы пользователя: Основная группа пользователя проверяется и обновляется, если необходимо. Например, если пользователь является суперпользователем, его основная группа устанавливается в группу "суперадминистраторов".
-
Обновление групп пользователя: Пользователь может быть членом нескольких групп. Если он присоединился к новой группе, его добавляют в таблицу групп. Если он покидает группу, его удаляют из этой группы.
-
Отправка уведомления по электронной почте: Если пользователь был неактивным и теперь активирован, ему отправляется уведомление на электронную почту о том, что его аккаунт был активирован.
-
Выполнение хуков: В случае наличия плагинов или расширений, которые обрабатывают события редактирования пользователя, они выполняются.
-
Очистка кэша авторизации: После обновления данных очищается кэш авторизации пользователя.
-
Логирование: Все изменения логируются для дальнейшего аудита.
-
Перенаправление: После успешного обновления данных пользователя происходит перенаправление на страницу редактирования этого пользователя, чтобы отобразить изменения.
Таким образом, этот код обновляет данные пользователя, гарантируя, что все связанные с ним данные в других модулях системы также будут актуализированы, и в случае необходимости отправляет уведомления и логирует действия.
$sql = $db->query("SELECT * FROM $db_users WHERE user_id=$id LIMIT 1"); // Выполняется SQL-запрос для получения данных пользователя по ID
$urr = $sql->fetch(); // Получаем результат запроса в виде ассоциативного массива
$title_params = array( // Создается массив параметров для заголовка
'EDIT' => $L['Edit'], // Заголовок страницы: "Edit"
'NAME' => $urr['user_name'] // Имя пользователя для отображения в заголовке
);
Cot::$out['subtitle'] = cot_title('{EDIT} - {NAME}', $title_params); // Формируем подзаголовок с использованием шаблона и параметров
if (!isset($out['head'])) { // Проверка, если еще не задано значение для head
Cot::$out['head'] = ''; // Инициализация переменной head, если она не была установлена
}
Cot::$out['head'] .= Cot::$R['code_noindex']; // Добавляем мета-тег noindex, чтобы поисковые системы не индексировали эту страницу
$mskin = cot_tplfile(['users', 'edit', $urr['user_maingrp']], 'module'); // Выбираем шаблон для редактирования, учитывая основную группу пользователя
/* === Hook === */
foreach (cot_getextplugins('users.edit.main') as $pl) { // Вставка плагинов, которые могут быть подключены к событию редактирования пользователя
include $pl; // Подключаем каждый найденный плагин
}
/* ===== */
require_once Cot::$cfg['system_dir'] . '/header.php'; // Подключаем системный файл заголовка
$t = new XTemplate($mskin); // Инициализируем объект шаблона XTemplate с выбранным шаблоном
require_once cot_incfile('forms'); // Подключаем файл с функциями для обработки форм
что происходит в данном участке кода:
-
Запрос к базе данных: Выполняется SQL-запрос для получения информации о пользователе по его
user_id. Результат запроса сохраняется в переменной$urr. -
Установка заголовка страницы: В массиве
$title_paramsформируются параметры для заголовка страницы. Заголовок страницы устанавливается с помощью функцииcot_title, которая подставляет значения из массива (например, название "Edit" и имя пользователя). -
Установка мета-тегов: Проверяется, был ли уже установлен элемент
head. Если нет, он инициализируется пустой строкой. Затем добавляется мета-тегnoindex, чтобы поисковые системы не индексировали эту страницу. -
Выбор шаблона: Выбирается шаблон для страницы редактирования пользователя. Шаблон подбирается в зависимости от основной группы пользователя, что позволяет использовать различные шаблоны для разных групп пользователей (например, для обычных пользователей или администраторов).
-
Хуки (расширения): Выполняются хуки через плагинную систему Cotonti. Если существуют подключенные плагины, которые реагируют на событие редактирования пользователя, их код будет включен и выполнен.
-
Загрузка заголовка: Подключается файл заголовка, который находится в директории
system_dir. Это может быть стандартный или кастомизированный заголовок страницы. -
Инициализация шаблона: Инициализируется объект XTemplate для выбранного шаблона. Это позволяет работать с переменными шаблона и динамически выводить данные на странице.
-
Подключение формы: Подключается файл с функциями для работы с формами, что позволяет использовать различные утилиты для обработки данных формы на странице редактирования пользователя.
Таким образом, весь этот участок кода подготавливает страницу для редактирования пользователя, включая настройки заголовков, шаблонов и мета-тегов, а также подключает необходимые ресурсы для дальнейшего отображения и обработки данных.
$protected = $sys['protecttopadmin'] ? array('disabled' => 'disabled') : array(); // Проверка, если защита от изменений для админа активирована, то массив будет содержать атрибут "disabled"
$editor_class = $cfg['users']['usertextimg'] ? 'minieditor' : ''; // Если в настройках включена возможность вставки изображений, то присваиваем классу значение 'minieditor', иначе строка остается пустой
$delete_pfs = cot_module_active('pfs') ? cot_checkbox(false, 'ruserdelpfs', $L['PFS']) : ''; // Если активен модуль pfs, добавляется чекбокс для удаления файлов пользователя, иначе оставляется пусто
$usersHelper = UsersHelper::getInstance(); // Инициализация экземпляра класса UsersHelper для работы с пользователями
$breadCrumbs = [ // Массив для формирования хлебных крошек
[cot_url('users'), Cot::$L['Users']], // Первая крошка с ссылкой на страницу пользователей
[
cot_url('users', ['m' => 'details', 'id' => $urr['user_id'], 'u' => $urr['user_name']]), // Вторая крошка со ссылкой на детальную информацию о пользователе
$usersHelper->getFullName($urr), // Имя пользователя, полученное с помощью хелпера
],
[cot_url('users', ['m' => 'edit', 'id' => $urr['user_id']]), Cot::$L['Edit']], // Третья крошка со ссылкой на страницу редактирования пользователя
];
$t->assign([ // Назначение значений для шаблона через XTemplate
'USERS_EDIT_TITLE' => htmlspecialchars($usersHelper->getFullName($urr)), // Заголовок редактирования пользователя: полное имя пользователя
'USERS_EDIT_SUBTITLE' => $L['useed_subtitle'], // Подзаголовок редактирования пользователя
'USERS_EDIT_BREADCRUMBS' => cot_breadcrumbs($breadCrumbs, Cot::$cfg['homebreadcrumb']), // Хлебные крошки для навигации
'USERS_EDIT_DETAILS_URL' => cot_url( // URL для перехода к подробной информации о пользователе
'users',
['m' => 'details', 'id' => $urr['user_id'], 'u' => $urr['user_name']]
),
'USERS_EDIT_EDIT_URL' => cot_url('users', ['m' => 'edit', 'id' => $urr['user_id']]), // URL для редактирования пользователя
'USERS_EDIT_SEND' => cot_url('users', 'm=edit&a=update&'.cot_xg().'&id='.$urr['user_id']), // URL для отправки данных обновления
'USERS_EDIT_ID' => $urr['user_id'], // Идентификатор пользователя
'USERS_EDIT_NAME' => cot_inputbox('text', 'rusername', $urr['user_name'], array('size' => 32, 'maxlength' => 100) + $protected), // Поле для ввода имени пользователя
'USERS_EDIT_THEME' => cot_selectbox_theme($urr['user_theme'], $urr['user_scheme'], 'rusertheme'), // Выбор темы для пользователя
'USERS_EDIT_LANG' => cot_selectbox_lang($urr['user_lang'], 'ruserlang'), // Выбор языка для пользователя
'USERS_EDIT_NEWPASS' => cot_inputbox('password', 'rusernewpass', '', array('size' => 12, 'maxlength' => 32, 'autocomplete' => 'off') + $protected), // Поле для ввода нового пароля пользователя
'USERS_EDIT_MAIN_GROUP' => cot_build_group($urr['user_maingrp']), // Основная группа пользователя
'USERS_EDIT_GROUPS' => cot_build_groupsms($urr['user_id'], $usr['isadmin'], $urr['user_maingrp']), // Группы пользователя
'USERS_EDIT_COUNTRY' => cot_selectbox_countries($urr['user_country'], 'rusercountry'), // Выбор страны для пользователя
'USERS_EDIT_EMAIL' => cot_inputbox('text', 'ruseremail', $urr['user_email'], array('size' => 32, 'maxlength' => 64)), // Поле для ввода email пользователя
'USERS_EDIT_HIDEEMAIL' => cot_radiobox($urr['user_hideemail'], 'ruserhideemail', array(1, 0), array($L['Yes'], $L['No'])), // Радио кнопки для скрытия email
'USERS_EDIT_TEXT' => cot_textarea('rusertext', $urr['user_text'], 4, 56, array('class' => $editor_class)), // Поле для текста пользователя (с редактором, если активирован)
'USERS_EDIT_GENDER' => cot_selectbox_gender($urr['user_gender'], 'rusergender'), // Выбор пола пользователя
'USERS_EDIT_BIRTHDATE' => cot_selectbox_date(cot_date2stamp($urr['user_birthdate']), 'short', 'ruserbirthdate', cot_date('Y', $sys['now']), cot_date('Y', $sys['now']) - 100, false), // Выбор даты рождения
'USERS_EDIT_TIMEZONE' => cot_selectbox_timezone($urr['user_timezone'], 'rusertimezone'), // Выбор часового пояса пользователя
'USERS_EDIT_REGDATE' => cot_date('datetime_medium', $urr['user_regdate']), // Дата регистрации пользователя
'USERS_EDIT_REGDATE_STAMP' => $urr['user_regdate'], // Временная метка регистрации
'USERS_EDIT_LASTLOG' => cot_date('datetime_medium', $urr['user_lastlog']), // Дата последнего входа пользователя
'USERS_EDIT_LASTLOG_STAMP' => $urr['user_lastlog'], // Временная метка последнего входа
'USERS_EDIT_LOGCOUNT' => $urr['user_logcount'], // Количество логинов пользователя
'USERS_EDIT_LASTIP' => cot_build_ipsearch($urr['user_lastip']), // IP-адрес последнего входа пользователя
'USERS_EDIT_DELETE' => (Cot::$sys['user_istopadmin']) // Если пользователь - топ-администратор, добавляется возможность удалить пользователя
? cot_radiobox(0, 'ruserdelete', [1, 0], [Cot::$L['Yes'], Cot::$L['No']]) . $delete_pfs // Радио кнопки для удаления пользователя
: Cot::$L['na'], // В противном случае выводится 'не доступно'
]);
В этом фрагменте кода происходит следующее:
-
Присваиваются данные для отображения на странице редактирования пользователя. Через объект
$tи методassign()заполняются переменные шаблона, которые будут использоваться для отображения информации о пользователе. -
Для каждого поля редактирования (например, имени, темы, языка, email и т.д.) подготавливаются значения, которые будут вставлены в форму. Эти значения включают в себя данные пользователя, такие как имя, email, дата регистрации, страна, пол, дата рождения и другие параметры, полученные из базы данных.
-
В некоторых случаях добавляются дополнительные настройки, например, для редактора текста или выпадающих списков с темами и языками. Если установлены определенные параметры (например, для полей "редактирование" или "удаление"), они обрабатываются с дополнительной логикой (например, условие для отображения радио кнопок для удаления пользователя, если текущий пользователь является топ-администратором).
-
Для каждого поля формы создаются соответствующие элементы, такие как текстовые поля, выпадающие списки, радиокнопки или текстовые области. Это позволяет администратору редактировать данные пользователя, такие как имя, email, группы, темы и другие параметры.
-
В конце концов, собранные данные передаются в шаблон, который будет отображать форму редактирования на веб-странице.
Основная цель этого фрагмента — подготовить данные для отображения на странице редактирования информации о пользователе, а также обеспечить возможность изменения этих данных через соответствующие элементы формы.
if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) { // Проверка наличия и значения параметра legacyMode в конфигурации
// @deprecated in 0.9.24 // Закомментированное предупреждение об устаревании
$t->assign([ // Присваивание значений в шаблон
//'USERS_EDIT_ACTIVE' => $user_form_active, // It seems it is obsolete code // Устаревший код, закомментирован
//'USERS_EDIT_BANNED' => $user_form_banned, // It seems it is obsolete code // Устаревший код, закомментирован
'USERS_EDIT_DETAILSLINK' => cot_url('users', 'm=details&id=' . $urr['user_id']), // Формирование ссылки на страницу деталей пользователя
'USERS_EDIT_EDITLINK' => cot_url('users', 'm=edit&id=' . $urr['user_id']), // Формирование ссылки на страницу редактирования пользователя
'USERS_EDIT_MAINGRP' => cot_build_group($urr['user_maingrp']), // Отображение основной группы пользователя
]); // Завершающая скобка массива для присваивания
} // Закрывающая скобка для условия legacyMode
В этом коде происходит следующее:
-
Проверяется наличие и значение параметра
legacyModeв конфигурации (Cot::$cfg['legacyMode']). Если этот параметр существует и равенtrue, тогда выполняется блок кода внутри условия. -
Внутри блока кода с использованием метода
assign()объекта шаблона$tзадаются следующие переменные для шаблона:USERS_EDIT_DETAILSLINK: Формируется ссылка на страницу деталей пользователя с использованием функцииcot_url()и ID пользователя.USERS_EDIT_EDITLINK: Формируется ссылка на страницу редактирования пользователя с использованием функцииcot_url()и ID пользователя.USERS_EDIT_MAINGRP: Используется функцияcot_build_group()для отображения основной группы пользователя (например, отображение названия группы, к которой принадлежит пользователь).
-
В коде закомментированы два устаревших параметра (
USERS_EDIT_ACTIVEиUSERS_EDIT_BANNED), которые, видимо, больше не используются, и их удаление помечено как "deprecated" (устаревшее). Это может означать, что эти переменные больше не влияют на работу кода и могут быть удалены в будущих версиях.
Основная цель этого кода — обеспечить поддержку старого функционала через параметр legacyMode, при этом формируя ссылки и данные, которые будут отображаться в шаблоне страницы редактирования пользователя, если режим устаревания включен.
// Extra fields // Комментарий, что обрабатываются дополнительные поля
if (!empty(Cot::$extrafields[Cot::$db->users])) { // Проверка, есть ли дополнительные поля для пользователей
foreach (Cot::$extrafields[Cot::$db->users] as $exfld) { // Процесс перебора всех дополнительных полей пользователей
$uname = strtoupper($exfld['field_name']); // Преобразование имени поля в верхний регистр для использования в шаблоне
$exfld_val = cot_build_extrafields('ruser' . $exfld['field_name'], $exfld, $urr['user_' . $exfld['field_name']]); // Формирование значения дополнительного поля
$exfld_title = cot_extrafield_title($exfld, 'user_'); // Получение заголовка для дополнительного поля
$t->assign([ // Присваивание значений в шаблон
'USERS_EDIT_' . $uname => $exfld_val, // Присваивание значения дополнительного поля
'USERS_EDIT_' . $uname . '_TITLE' => $exfld_title, // Присваивание заголовка дополнительного поля
'USERS_EDIT_EXTRAFLD' => $exfld_val, // Присваивание значения дополнительного поля (возможно, для общего использования)
'USERS_EDIT_EXTRAFLD_TITLE' => $exfld_title, // Присваивание заголовка дополнительного поля (возможно, для общего использования)
]);
$t->parse('MAIN.EXTRAFLD'); // Парсинг шаблона блока EXTRAFLD
}
} // Закрывающая скобка для условия наличия дополнительных полей
// Error and message reporting // Комментарий, что будет произведен вывод сообщений об ошибках и других уведомлений
cot_display_messages($t); // Вызов функции для отображения сообщений на странице, передача объекта шаблона для вывода
/* === Hook === */ // Начало блока плагинов
foreach (cot_getextplugins('users.edit.tags') as $pl) // Перебор плагинов, зарегистрированных для хука 'users.edit.tags'
{
include $pl; // Подключение плагина
}
/* ===== */ // Конец блока плагинов
$t->parse('MAIN'); // Парсинг основного блока 'MAIN' шаблона
$t->out('MAIN'); // Вывод обработанного шаблона основного блока 'MAIN'
require_once Cot::$cfg['system_dir'] . '/footer.php'; // Подключение файла футера (нижней части страницы)
В этом фрагменте происходит несколько действий:
-
Отображение сообщений об ошибках и уведомлений: Сначала вызывается функция, которая занимается выводом сообщений, таких как ошибки или информационные уведомления, на страницу. Это важно для взаимодействия с пользователем, чтобы он мог увидеть ошибки или другие важные сообщения.
-
Подключение плагинов: Затем идет цикл, в котором перебираются все подключенные к системе плагины, связанные с хуком
users.edit.tags. Для каждого найденного плагина происходит его подключение. Это позволяет расширять функциональность шаблона с помощью дополнительных плагинов. -
Парсинг и вывод основного шаблона: Далее происходит парсинг основного шаблона с помощью метода
parse, который обрабатывает контент и присваивает его объекту шаблона. После этого, с помощью методаout, выводится результат парсинга. -
Подключение футера: В конце подключается файл футера, который обычно содержит элементы, такие как закрывающие теги HTML, информацию о лицензии или другие компоненты, которые должны быть на каждой странице сайта.
Таким образом, этот код отвечает за завершение обработки страницы и вывод всех необходимых элементов интерфейса, включая сообщения, дополнительные плагины и завершающие компоненты страницы.
Комментарии (0)
Автор контента
Оффлайн
Sodium Carbonate
Последняя авторизация: 20.07.2026 04:22
- Страница размещена: 31.01.2025 00:43
- Последнее обновление: 31.01.2025 01:12