*/ protected Collection $checkers; /** * Whether checkers are sorted by priority. */ protected bool $sorted = false; public function __construct() { $this->checkers = new Collection; $this->registerDefaultCheckers(); } /** * Register the default name checkers. */ protected function registerDefaultCheckers(): void { $this->addChecker(new TvNameChecker); $this->addChecker(new MovieNameChecker); $this->addChecker(new GameNameChecker); $this->addChecker(new AppNameChecker); } /** * Add a name checker to the service. */ public function addChecker(NameCheckerInterface $checker): self { $this->checkers->push($checker); $this->sorted = false; return $this; } /** * Check a release name against all registered checkers. * * @param object $release The release object * @param string $textstring The text to check * @return NameFixResult|null The first matching result, or null if no match */ public function check(object $release, string $textstring): ?NameFixResult { $this->ensureSorted(); foreach ($this->checkers as $checker) { $result = $checker->check($release, $textstring); if ($result !== null) { return $result; } } return null; } /** * Check all registered checkers and return all matches. * * Useful for debugging or when you want to see all potential matches. * * @param object $release The release object * @param string $textstring The text to check * @return Collection All matching results */ public function checkAll(object $release, string $textstring): Collection { $this->ensureSorted(); $results = new Collection; foreach ($this->checkers as $checker) { $result = $checker->check($release, $textstring); if ($result !== null) { $results->push($result); } } return $results; } /** * Check using a specific checker by name. * * @param string $checkerName The name of the checker to use * @param object $release The release object * @param string $textstring The text to check * @return NameFixResult|null The result if matched, null otherwise */ public function checkWith(string $checkerName, object $release, string $textstring): ?NameFixResult { $checker = $this->checkers->first( fn (NameCheckerInterface $c) => strtolower($c->getName()) === strtolower($checkerName) ); return $checker?->check($release, $textstring); } /** * Get all registered checkers. * * @return Collection */ public function getCheckers(): Collection { $this->ensureSorted(); return $this->checkers; } /** * Get checker statistics. * * @return array */ public function getStats(): array { return $this->checkers->map(fn (NameCheckerInterface $checker) => [ 'name' => $checker->getName(), 'priority' => $checker->getPriority(), 'class' => get_class($checker), ])->toArray(); } /** * Ensure checkers are sorted by priority. */ protected function ensureSorted(): void { if (! $this->sorted) { $this->checkers = $this->checkers->sortBy( fn (NameCheckerInterface $checker) => $checker->getPriority() )->values(); $this->sorted = true; } } }