lthn.io/app/Core/Database/Seeders/SeederRegistry.php
Claude 41a90cbff8
feat: lthn.io API serving live chain data
Fixed: basePath self→static binding, namespace detection, event wiring,
SQLite cache, file cache driver. All Mod Boot classes converted to
$listens pattern for lifecycle event discovery.

Working endpoints:
- /v1/explorer/info — live chain height, difficulty, aliases
- /v1/explorer/stats — formatted chain statistics
- /v1/names/directory — alias directory grouped by type
- /v1/names/available/{name} — name availability check
- /v1/names/lookup/{name} — name details

Co-Authored-By: Charon <charon@lethean.io>
2026-04-03 17:17:42 +01:00

189 lines
5 KiB
PHP

<?php
/*
* Core PHP Framework
*
* Licensed under the European Union Public Licence (EUPL) v1.2.
* See LICENSE file for details.
*/
declare(strict_types=1);
namespace Core\Database\Seeders;
use Core\Database\Seeders\Exceptions\CircularDependencyException;
/**
* Manual seeder registration for explicit control over seeder ordering.
*
* Use SeederRegistry when you want explicit control over which seeders run
* and in what order, rather than relying on auto-discovery.
*
* ## Example
*
* ```php
* $registry = new SeederRegistry();
*
* $registry
* ->register(FeatureSeeder::class, priority: 10)
* ->register(PackageSeeder::class, after: [FeatureSeeder::class])
* ->register(WorkspaceSeeder::class, after: [PackageSeeder::class]);
*
* // Get ordered seeders
* $seeders = $registry->getOrdered();
* ```
*
*
* @see SeederDiscovery For auto-discovered seeders
*/
class SeederRegistry
{
/**
* Registered seeder metadata.
*
* @var array<string, array{priority: int, after: array<string>, before: array<string>}>
*/
private array $seeders = [];
/**
* Register a seeder class.
*
* @param string $class Fully qualified seeder class name
* @param int $priority Priority (higher runs first, default 50)
* @param array<string> $after Seeders that must run before this one
* @param array<string> $before Seeders that must run after this one
* @return $this
*/
public function register(
string $class,
int $priority = SeederDiscovery::DEFAULT_PRIORITY,
array $after = [],
array $before = []
): self {
$this->seeders[$class] = [
'priority' => $priority,
'after' => $after,
'before' => $before,
];
return $this;
}
/**
* Register multiple seeders at once.
*
* @param array<string, array{priority?: int, after?: array<string>, before?: array<string>}|int> $seeders
* Either [Class => priority] or [Class => ['priority' => n, 'after' => [], 'before' => []]]
* @return $this
*/
public function registerMany(array $seeders): self
{
foreach ($seeders as $class => $config) {
if (is_int($config)) {
$this->register($class, priority: $config);
} else {
$this->register(
$class,
priority: $config['priority'] ?? SeederDiscovery::DEFAULT_PRIORITY,
after: $config['after'] ?? [],
before: $config['before'] ?? []
);
}
}
return $this;
}
/**
* Remove a seeder from the registry.
*
* @param string $class Seeder class to remove
* @return $this
*/
public function remove(string $class): self
{
unset($this->seeders[$class]);
return $this;
}
/**
* Check if a seeder is registered.
*
* @param string $class Seeder class to check
*/
public function has(string $class): bool
{
return isset($this->seeders[$class]);
}
/**
* Get all registered seeders.
*
* @return array<string, array{priority: int, after: array<string>, before: array<string>}>
*/
public function all(): array
{
return $this->seeders;
}
/**
* Get ordered seeder classes.
*
* @return array<string> Ordered list of seeder class names
*
* @throws CircularDependencyException If a circular dependency is detected
*/
public function getOrdered(): array
{
// Use SeederDiscovery's sorting logic by creating a temporary instance
$discovery = new class extends SeederDiscovery
{
/**
* @param array<string, array{priority: int, after: array<string>, before: array<string>}> $seeders
*/
public function setSeeders(array $seeders): void
{
$reflection = new \ReflectionClass(SeederDiscovery::class);
$prop = $reflection->getProperty('seeders');
$prop->setValue($this, $seeders);
$discovered = $reflection->getProperty('discovered');
$discovered->setValue($this, true);
}
};
$discovery->setSeeders($this->seeders);
return $discovery->discover();
}
/**
* Merge another registry into this one.
*
* @param SeederRegistry $registry Registry to merge
* @return $this
*/
public function merge(SeederRegistry $registry): self
{
foreach ($registry->all() as $class => $meta) {
if (! isset($this->seeders[$class])) {
$this->seeders[$class] = $meta;
}
}
return $this;
}
/**
* Clear all registered seeders.
*
* @return $this
*/
public function clear(): self
{
$this->seeders = [];
return $this;
}
}