128 lines
2.4 KiB
PHP
128 lines
2.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Kiri\Router\Annotate;
|
|
|
|
class DeferRegistry
|
|
{
|
|
|
|
/**
|
|
* @var array<string, Defer[]> "ClassName::method" => Defer[]
|
|
*/
|
|
private static array $registry = [];
|
|
|
|
|
|
/**
|
|
* @param string $class
|
|
* @param string $method
|
|
* @param Defer $defer
|
|
* @return void
|
|
*/
|
|
public static function add(string $class, string $method, Defer $defer): void
|
|
{
|
|
$key = self::key($class, $method);
|
|
self::$registry[$key][] = $defer;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $class
|
|
* @param string $method
|
|
* @return Defer[]
|
|
*/
|
|
public static function get(string $class, string $method): array
|
|
{
|
|
return self::$registry[self::key($class, $method)] ?? [];
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $class
|
|
* @return bool
|
|
*/
|
|
public static function hasAny(string $class): bool
|
|
{
|
|
$prefix = $class . '::';
|
|
foreach (array_keys(self::$registry) as $key) {
|
|
if (str_starts_with($key, $prefix)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $class
|
|
* @return array<string, Defer[]> method => Defer[]
|
|
*/
|
|
public static function getAll(string $class): array
|
|
{
|
|
$result = [];
|
|
$prefix = $class . '::';
|
|
foreach (self::$registry as $key => $defers) {
|
|
if (str_starts_with($key, $prefix)) {
|
|
$method = substr($key, strlen($prefix));
|
|
$result[$method] = $defers;
|
|
}
|
|
}
|
|
return $result;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $class
|
|
* @param string $method
|
|
* @return void
|
|
*/
|
|
public static function execute(string $class, string $method): void
|
|
{
|
|
$key = self::key($class, $method);
|
|
if (!isset(self::$registry[$key])) {
|
|
return;
|
|
}
|
|
|
|
$defers = self::$registry[$key];
|
|
unset(self::$registry[$key]);
|
|
|
|
foreach ($defers as $defer) {
|
|
try {
|
|
$callback = $defer->callback;
|
|
$params = $defer->params;
|
|
|
|
if (is_array($callback)) {
|
|
[$cbClass, $cbMethod] = $callback;
|
|
$instance = \Kiri::getDi()->get($cbClass);
|
|
call_user_func([$instance, $cbMethod], ...$params);
|
|
} else {
|
|
$instance = \Kiri::getDi()->get($callback);
|
|
call_user_func([$instance, '__invoke'], ...$params);
|
|
}
|
|
} catch (\Throwable $throwable) {
|
|
\Kiri::getLogger()->error('Defer callback failed: ' . $throwable->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
public static function clear(): void
|
|
{
|
|
self::$registry = [];
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $class
|
|
* @param string $method
|
|
* @return string
|
|
*/
|
|
private static function key(string $class, string $method): string
|
|
{
|
|
return $class . '::' . $method;
|
|
}
|
|
|
|
}
|