vk/mirzaev/vk/system/core.php

268 lines
8.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace mirzaev\vk;
use mirzaev\vk\robots\robot;
use mirzaev\vk\traits\singleton;
use mirzaev\vk\loggers\jasmo;
use exception;
/**
* Ядро
*
* @property-read int $robots Количество роботов
* @property string $timezone Временная зона (журналирование)
* @property array $path Пути (архитектура проекта)
*
* @method protected static function __construct() Инициализация
* @method public static function init() Запуск инициализации или получение инстанции
* @method public public function build() Сборщик
* @method public function set($id, $value) Запись в реестр
* @method public function get($id = null) Чтение из реестра
*
* @package mirzaev\vk
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
*/
final class core
{
use singleton;
/**
* Счётчик роботов
*/
private int $robots = 0;
/**
* Реестр роботов
*/
private array $registry = [];
/**
* Временная зона
*
* Используется в логировании
*/
private readonly string $timezone;
/**
* Путь до корня проекта
*/
private readonly string $path_root;
/**
* Путь до папки журналов
*/
private readonly string $path_logs;
/**
* Путь до временной папки
*/
private readonly string $path_temp;
/**
* Запись в журнал
*
* @param string $file Файл для журналирования
*
* @return self
*
* @todo Добавить установку иного журналиста по спецификации PSR-3
*/
public function journal(string $file = null): self
{
// Инициализация журналиста (требует переработки)
jasmo::init()::post($file)::postErrorHandler()::postShutdownHandler();
return $this;
}
/**
* Записать в реестр
*
* @param int $id
* @param robot $robot
*
* @see mirzaev\vk\traits\registry Модификация метода
*
* @return void
*/
public function write(int $id, robot $robot): void
{
try {
// Инициализация уникального идентификатора сессии
$session = count($this->read($id));
} catch (exception $e) {
if ($e->getCode() === 404) {
// Робота или сессии не существует
$session = 0;
}
} finally {
// Записать новую сессию
$this->registry[$id][$session] = $robot;
// Прединкрементация счётчика роботов
++$this->robots;
}
}
/**
* Прочитать из реестра
*
* Если не передать идентификатор, то вернёт все значения
*
* @param int|null $id Идентификатор
* @param int|null $session Сессия
*
* @see mirzaev\vk\traits\registry Модификация метода
*
* @return mixed Весь реестр, робота или сессию робота
*/
public function read(int|null $id = null, int|null $session = null): mixed
{
if (isset($id)) {
// Робот передан
if (array_key_exists($id, $this->registry)) {
// Робот найден
if (isset($session)) {
// Сессия робота передана
if (array_key_exists($session, $this->registry[$id])) {
// Сессия робота найдена
return $this->registry[$id][$session];
}
throw new exception("Сессия $session робота с идентификатором $id не найдена", 404);
}
return $this->registry[$id];
} else {
throw new exception("Робот с идентификатором $id не найден", 404);
}
}
return $this->registry;
}
/**
* Удалить из реестра
*
* @param int|null $id Идентификатор
* @param int|null $session Сессия
*
* @return void
*
* @see mirzaev\vk\traits\registry Модификация метода
*/
public function delete(int|null $id = null, int|null $session = null): void
{
if (isset($id)) {
// Робот передан
if (array_key_exists($id, $this->registry)) {
// Робот найден
if (isset($session)) {
// Сессия передана
if (array_key_exists($session, $this->registry[$id])) {
// Сессия найдена
// Постдекрементация счётчика роботов
--$this->robots;
// Удаление сессии
unset($this->registry[$id][$session]);
return;
}
throw new exception("Сессия $session робота с идентификатором $id не найдена", 404);
}
// Вычитание из счётчика количества сессий робота
$this->robots = $this->robots - count($this->registry[$id]);
// Удаление робота и всех его сессий
unset($this->registry[$id]);
return;
}
throw new exception("Робот с идентификатором $id не найден", 404);
}
// Полная очистка
$this->registry = [];
}
/**
* Записать свойство
*
* @param string $name Название
* @param mixed $value Значение
*
* @return void
*/
public function __set(string $name, mixed $value): void
{
match ($name) {
'timezone' => !isset($this->timezone) ? $this->timezone = $value : throw new exception('Запрещено переопределять часовой пояс', 500),
'path_root' => !isset($this->path_root) ? $this->path_root = $value : throw new exception('Запрещено переопределять корневой каталог', 500),
'path_logs' => !isset($this->path_logs) ? $this->path_logs = $value : throw new exception('Запрещено переопределять каталог журналов', 500),
'path_temp' => !isset($this->path_temp) ? $this->path_temp = $value : throw new exception('Запрещено переопределять каталог временных файлов', 500),
default => throw new exception("Свойство $name не обнаружено", 404)
};
}
/**
* Прочитать свойство
*
* Записывает значение по умолчанию, если свойство не инициализировано
*
* @param mixed $name Название
*
* @return mixed
*/
public function __get(string $name): mixed
{
return match ($name) {
'robots' => $this->robots,
'timezone' => $this->timezone ?? $this->timezone = 'Europe/Moscow',
'path_root' => $this->path_root ?? $this->path_root = dirname(__DIR__),
'path_logs' => $this->path_logs ?? $this->path_logs = $this->__get('path_root') . '/logs',
'path_temp' => $this->path_temp ?? $this->path_temp = $this->__get('path_root') . '/temp',
default => throw new exception("Свойство \"\$$name\" не обнаружено", 404)
};
}
/**
* Вызвать метод
*
* Ищет класс описывающий робота,
* создаёт и возвращает его объект
*
* @param string $method Метод
* @param array $params Параметры
*
* @return robot
*/
public function __call(string $method, array $params): robot
{
if (class_exists($robot = '\\mirzaev\\vk\\robots\\' . $method)) {
// Если найден класс реализующий запрошенного робота
return new $robot(...$params);
} else {
throw new exception("Робот $method не найден", 404);
}
}
}