Файл ServerEventService.php в Cotonti
Основное назначение файла ServerEventService.php в движке Cotonti CMF — это управление и обработка серверных событий для пользователей, которые подключены к системе и слушают события. Этот класс предоставляет методы для создания, удаления и очистки событий, связанных с пользователями. Сервис работает с событиями в реальном времени, взаимодействуя с базой данных и таблицами, связанными с этими событиями.
Суть содержания кода:
-
Регистрация событий для пользователя: Класс позволяет создавать события для пользователей, если у них есть активные сессии (через метод
createForUser). Это может быть полезно для отправки уведомлений или обновлений пользователю в реальном времени, если он подключен. -
Удаление устаревших событий: Метод
deleteByUserIdудаляет данные о событиях для конкретного пользователя. Он учитывает как время создания события (чтобы удалить старые события), так и активность пользователя. Если пользователь больше не имеет активных сессий, то все его старые события могут быть удалены. -
Очистка устаревших событий: Метод
clearExpiredочищает все события, которые устарели (прошли определенное время), а также события для пользователей, которые больше не подключены к серверу. Это позволяет поддерживать чистоту базы данных, удаляя данные, которые больше не актуальны. -
Подключение к базе данных: Для работы с данными используется объект
Cot::$db, который позволяет выполнять запросы на вставку, обновление и удаление данных. Все операции с таблицами событий и наблюдателей событий производятся с помощью SQL-запросов. -
Проверка сессий пользователя: Прежде чем создать событие, сервис проверяет, есть ли у пользователя активные сессии. Если сессий нет, событие не создается. Это предотвращает создание событий для пользователей, которые не подключены к серверу.
-
Метод для получения токена: Метод
getTokenForCurrentUserвозвращает уникальный идентификатор для текущей сессии пользователя, который может быть использован для идентификации пользователя при работе с событиями.
Методы класса:
createForUser(int $userId, string $eventName, array $data = []): bool— Создает событие для пользователя, если у него есть активные сессии.deleteByUserId(int $userId): void— Удаляет события пользователя, если его сессии больше нет или если события устарели.clearExpired(): void— Очищает все устаревшие события и события для пользователей, которые больше не подключены.getTokenForCurrentUser(): string— Возвращает уникальный токен для текущей сессии пользователя.
Стиль PHP:
- Современный стиль PHP: Код использует строгую типизацию, что указывает на использование более современной практики программирования.
- Обработка ошибок: Для обработки ошибок используется выбрасывание исключений (
BadMethodCallException), что помогает избегать неожиданных сбоев. - Паттерн Singleton: Класс использует трейт
GetInstanceTraitдля реализации паттерна Singleton, что гарантирует наличие только одного экземпляра этого класса. - Работа с базой данных: Прямое взаимодействие с базой данных через объект
Cot::$db, что является стандартом для большинства фреймворков PHP.
/system/serverEvents/ServerEventService.php
<?php
declare(strict_types=1); // Задает строгую типизацию в PHP, что означает, что типы данных будут проверяться во время выполнения.
namespace cot\serverEvents; // Определяет пространство имен для текущего класса.
use Cot; // Импортирует класс Cot, который предоставляет доступ к основным системным функциям Cotonti.
use cot\serverEvents\repositories\ServerEventsObserversRepository; // Импортирует репозиторий для работы с наблюдателями событий.
use cot\traits\GetInstanceTrait; // Импортирует трейт для реализации паттерна Singleton.
use BadMethodCallException; // Импортирует исключение для обработки ошибок вызова методов.
defined('COT_CODE') or die('Wrong URL'); // Проверяет, что файл был вызван через основной фреймворк, иначе завершает выполнение.
class ServerEventService // Определяет класс для работы с серверными событиями.
{
use GetInstanceTrait; // Использует трейт для реализации Singleton.
public function createForUser(int $userId, string $eventName, array $data = []): bool
{
if ($userId < 1) { // Если идентификатор пользователя некорректен.
throw new BadMethodCallException(); // Выбрасывает исключение, так как ID пользователя должен быть больше нуля.
}
$sessionsCount = ServerEventsObserversRepository::getInstance()->getCountByUserId($userId); // Получает количество активных сессий для данного пользователя.
if ($sessionsCount === 0) { // Если у пользователя нет активных сессий.
return false; // Возвращает false, так как пользователь не слушает события.
}
$data = [ // Создает массив данных для вставки события в базу данных.
'user_id' => $userId, // Идентификатор пользователя.
'event' => $eventName, // Имя события.
'data' => json_encode($data), // Преобразует дополнительные данные события в формат JSON.
'created_at' => date('Y-m-d H:i:s'), // Время создания события.
];
$result = Cot::$db->insert(Cot::$db->server_events, $data); // Вставляет событие в таблицу событий.
return $result > 0; // Если результат больше нуля, то событие успешно добавлено.
}
public function deleteByUserId(int $userId): void
{
if ($userId === 0) { // Если ID пользователя равен нулю.
throw new BadMethodCallException(); // Выбрасывает исключение, так как ID пользователя не может быть равен нулю.
}
$table = Cot::$db->quoteTableName(Cot::$db->server_events); // Получает безопасное имя таблицы событий.
$observersTable = Cot::$db->quoteTableName(Cot::$db->server_events_observers); // Получает безопасное имя таблицы наблюдателей событий.
$expiredCondition = "{$table}.created_at <= '" // Создает условие для удаления событий, которые устарели.
. date('Y-m-d H:i:s', time() - ServerEventsDictionary::EVENT_EXPIRE_IN) . "'"; // Проверяет, что событие устарело.
$sessionsCount = ServerEventsObserversRepository::getInstance()->getCountByUserId($userId); // Получает количество сессий для пользователя.
$params = ['userId' => $userId]; // Параметры запроса.
if ($sessionsCount === 0) { // Если у пользователя нет активных сессий.
$condition = "{$table}.user_id = :userId OR ({$expiredCondition})"; // Условие для удаления всех его событий или устаревших событий.
} else { // Если у пользователя есть активные сессии.
$lastData = Cot::$db->query( // Получает данные последнего события пользователя.
"SELECT MIN(last_event_id) as last_event_id, MIN(updated_at) as min_created_at "
. " FROM {$observersTable} WHERE user_id = :userId GROUP BY user_id",
['userId' => $userId]
)->fetch(); // Выполняет запрос и получает результат.
if (empty($lastData)) { // Если нет данных о последнем событии.
return; // Возвращает управление, так как нечего удалять.
}
$deleteConditions = [ // Условия для удаления событий пользователя.
"{$table}.created_at <= '{$lastData['min_created_at']}'", // Удаляет события, которые старше времени последнего обновления.
];
if ($lastData['last_event_id'] > 0) { // Если ID последнего события больше нуля.
$deleteConditions[] = "{$table}.id <= {$lastData['last_event_id']}"; // Добавляет условие для удаления событий до этого ID.
}
$condition = "({$table}.user_id = :userId AND (" . implode(' OR ', $deleteConditions) . ")) "
. " OR ({$expiredCondition})"; // Создает полное условие для удаления событий.
}
Cot::$db->delete(Cot::$db->server_events, $condition, $params); // Выполняет удаление событий по сформированному условию.
}
public function clearExpired(): void
{
$table = Cot::$db->quoteTableName(Cot::$db->server_events); // Получает безопасное имя таблицы событий.
$observersTable = Cot::$db->quoteTableName(Cot::$db->server_events_observers); // Получает безопасное имя таблицы наблюдателей.
$condition = "{$table}.created_at <= '" // Создает условие для удаления устаревших событий.
. date('Y-m-d H:i:s', time() - ServerEventsDictionary::EVENT_EXPIRE_IN) . "' "
. " OR {$table}.user_id NOT IN (SELECT DISTINCT user_id FROM {$observersTable})"; // Удаляет события для пользователей, которые больше не наблюдают за событиями.
Cot::$db->delete(Cot::$db->server_events, $condition); // Выполняет удаление устаревших событий по сформированному условию.
}
}
Комментарии (0)
Автор контента
Оффлайн
Administrator
Последняя авторизация: 05.07.2026 18:32
- Страница размещена: 27.01.2025 23:44
- Последнее обновление: 27.01.2025 23:44