284 lines
8.4 KiB
PHP
284 lines
8.4 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace hood\vk;
|
||
|
||
use Exception;
|
||
use hood\vk\loggers\jasmo,
|
||
hood\vk\traits\singleton,
|
||
hood\vk\robots\robot;
|
||
|
||
/**
|
||
* Ядро
|
||
*
|
||
* @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 VK
|
||
* @author Арсен Мирзаев <red@hood.su>
|
||
*/
|
||
final class core
|
||
{
|
||
use singleton;
|
||
|
||
/**
|
||
* Счётчик роботов
|
||
*
|
||
* @var int
|
||
*/
|
||
private int $robots = 0;
|
||
|
||
/**
|
||
* Реестр роботов
|
||
*
|
||
* @var array
|
||
*/
|
||
private array $registry = [];
|
||
|
||
/**
|
||
* Временная зона
|
||
*
|
||
* Используется в логировании
|
||
*
|
||
* @var string
|
||
*/
|
||
private string $timezone;
|
||
|
||
/**
|
||
* Путь до корня проекта
|
||
*
|
||
* @var string
|
||
*/
|
||
private string $path_root;
|
||
|
||
/**
|
||
* Путь до папки журналов
|
||
*
|
||
* @var string
|
||
*/
|
||
private string $path_logs;
|
||
|
||
/**
|
||
* Путь до временной папки
|
||
*
|
||
* @var string
|
||
*/
|
||
private string $path_temp;
|
||
|
||
/**
|
||
* Журналист
|
||
*
|
||
* @param string $file Файл для журналирования
|
||
*
|
||
* @return self
|
||
*
|
||
* @todo Добавить установку иного журналиста по спецификации PSR-3
|
||
* @todo Более гибкое журналирование
|
||
*/
|
||
public function log(string $file = null): self
|
||
{
|
||
// Инициализация журналиста (требует переработки)
|
||
jasmo::init()::post($file)::postErrorHandler()::postShutdownHandler();
|
||
|
||
return $this;
|
||
}
|
||
|
||
/**
|
||
* Записать в реестр
|
||
*
|
||
* @param int $id
|
||
* @param robot $robot
|
||
*
|
||
* @see hood\vk\traits\registry Модификация метода
|
||
*
|
||
* @return void
|
||
*/
|
||
public function set(int $id, robot $robot): void
|
||
{
|
||
// if (empty($this->registry[$id])) {
|
||
// // Если нет сессий, то инициализировать
|
||
// $this->registry[$id] = [];
|
||
// }
|
||
|
||
// Создать новую сессию и обновить счётчик роботов
|
||
$this->registry[$id][++$this->robots] = $robot;
|
||
}
|
||
|
||
/**
|
||
* Прочитать из реестра
|
||
*
|
||
* Если не передать идентификатор, то вернёт все значения
|
||
*
|
||
* @param int|null $id Идентификатор
|
||
* @param int|null $session Сессия
|
||
*
|
||
* @see hood\vk\traits\registry Модификация метода
|
||
*
|
||
* @return mixed
|
||
*/
|
||
public function get(int $id = null, int $session = null)
|
||
{
|
||
if (isset($id) && array_key_exists($id, $this->registry)) {
|
||
// Робот передан и найден
|
||
if (isset($session) && array_key_exists($session, $this->registry[$id])) {
|
||
// Сессия робота передана и найдена
|
||
return $this->registry[$id][$session];
|
||
}
|
||
return $this->registry[$id];
|
||
}
|
||
return $this->registry;
|
||
}
|
||
|
||
/**
|
||
* Удалить из реестра
|
||
*
|
||
* @param int|null $id Идентификатор
|
||
* @param int|null $session Сессия
|
||
*
|
||
* @see hood\vk\traits\registry Модификация метода
|
||
*
|
||
* @return void
|
||
*/
|
||
public function delete(int $id = null, int $session = null): void
|
||
{
|
||
if (isset($id)) {
|
||
// Робот передан
|
||
|
||
if (!array_key_exists($id, $this->registry)) {
|
||
throw new Exception('Робот не найден');
|
||
}
|
||
|
||
if (isset($session)) {
|
||
// Сессия передана
|
||
|
||
if (!array_key_exists($session, $this->registry[$id])) {
|
||
throw new Exception('Сессия не найдена');
|
||
}
|
||
|
||
// Счётчик роботов
|
||
--$this->robots;
|
||
|
||
// Удаление сессии
|
||
unset($this->registry[$id][$session]);
|
||
|
||
return;
|
||
}
|
||
|
||
// Счётчик роботов
|
||
$this->robots = $this->robots - count($this->registry[$id]);
|
||
|
||
// Удаление робота и всех его сессий
|
||
unset($this->registry[$id]);
|
||
|
||
return;
|
||
}
|
||
|
||
// Удаление всех роботов и их сессий
|
||
$this->registry = [];
|
||
}
|
||
|
||
/**
|
||
* Записать свойство
|
||
*
|
||
* @param mixed $name Название
|
||
* @param mixed $value Значение
|
||
*
|
||
* @return void
|
||
*/
|
||
public function __set($name, $value): void
|
||
{
|
||
if ($name === 'timezone') {
|
||
if (!isset($this->timezone)) {
|
||
$this->timezone = $value;
|
||
} else {
|
||
throw new Exception('Запрещено переопределять часовой пояс');
|
||
}
|
||
} else if ($name === 'path_root') {
|
||
if (!isset($this->path_root)) {
|
||
$this->path_root = $value;
|
||
} else {
|
||
throw new Exception('Запрещено переопределять корневой каталог');
|
||
}
|
||
} else if ($name === 'path_logs') {
|
||
if (!isset($this->path_logs)) {
|
||
$this->path_logs = $value;
|
||
} else {
|
||
throw new Exception('Запрещено переопределять каталог журналов');
|
||
}
|
||
} else if ($name === 'path_temp') {
|
||
if (!isset($this->path_temp)) {
|
||
$this->path_temp = $value;
|
||
} else {
|
||
throw new Exception('Запрещено переопределять каталог временных файлов');
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Прочитать свойство
|
||
*
|
||
* @param mixed $name Название
|
||
*
|
||
* @return mixed
|
||
*/
|
||
public function __get($name)
|
||
{
|
||
if ($name === 'robots') {
|
||
return $this->robots;
|
||
} else if ($name === 'timezone') {
|
||
if (!isset($this->timezone)) {
|
||
// Значение по умолчанию
|
||
$this->timezone = 'Europe/Moscow';
|
||
}
|
||
return $this->timezone;
|
||
} else if ($name === 'path_root') {
|
||
if (!isset($this->path_root)) {
|
||
// Значение по умолчанию
|
||
$this->path_root = dirname(__DIR__);
|
||
}
|
||
return $this->path_root;
|
||
} else if ($name === 'path_logs') {
|
||
if (!isset($this->path_logs)) {
|
||
// Значение по умолчанию
|
||
$this->path_logs = $this->path_root . '/logs';
|
||
}
|
||
return $this->path_logs;
|
||
} else if ($name === 'path_temp') {
|
||
if (!isset($this->path_temp)) {
|
||
// Значение по умолчанию
|
||
$this->path_temp = $this->path_root . '/temp';
|
||
}
|
||
return $this->path_temp;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Вызвать метод
|
||
*
|
||
* Ищет класс описывающий робота,
|
||
* создаёт и возвращает его объект
|
||
*
|
||
* @param string $method Метод
|
||
* @param array $params Параметры
|
||
*
|
||
* @return robot
|
||
*/
|
||
public function __call(string $method, array $params): robot
|
||
{
|
||
if (class_exists($robot = '\\hood\\vk\\robots\\' . $method)) {
|
||
// Если найден класс реализующий запрошенного робота
|
||
return new $robot(...$params);
|
||
} else {
|
||
throw new Exception('Не найден робот: ' . $method);
|
||
}
|
||
}
|
||
}
|