respect-validation/library/Factory.php
Henrique Moody e56836c4f1
Remove deprecated rules
We want to release version 3.0 as fresh as possible, without having to
maintain backward compatibility with the previous versions. Apart from
that, for some rules, it's impossible to be compatible with older
versions.

Acked-by: Alexandre Gomes Gaigalas <alganet@gmail.com>
2025-12-18 17:22:51 +01:00

91 lines
2.6 KiB
PHP

<?php
/*
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
* SPDX-License-Identifier: MIT
*/
declare(strict_types=1);
namespace Respect\Validation;
use ReflectionClass;
use ReflectionException;
use Respect\Validation\Exceptions\ComponentException;
use Respect\Validation\Exceptions\InvalidClassException;
use Respect\Validation\Transformers\Prefix;
use Respect\Validation\Transformers\RuleSpec;
use Respect\Validation\Transformers\Transformer;
use function array_merge;
use function sprintf;
use function trim;
use function ucfirst;
final class Factory
{
/**
* @var string[]
*/
private array $rulesNamespaces = ['Respect\\Validation\\Rules'];
public function __construct(
private readonly Transformer $transformer = new Prefix()
) {
}
public function withRuleNamespace(string $rulesNamespace): self
{
$clone = clone $this;
$clone->rulesNamespaces[] = trim($rulesNamespace, '\\');
return $clone;
}
/**
* @param mixed[] $arguments
*/
public function rule(string $ruleName, array $arguments = []): Rule
{
return $this->createRuleSpec($this->transformer->transform(new RuleSpec($ruleName, $arguments)));
}
private function createRuleSpec(RuleSpec $ruleSpec): Rule
{
$rule = $this->createRule($ruleSpec->name, $ruleSpec->arguments);
if ($ruleSpec->wrapper !== null) {
return $this->createRule($ruleSpec->wrapper->name, array_merge($ruleSpec->wrapper->arguments, [$rule]));
}
return $rule;
}
/**
* @param mixed[] $arguments
*/
private function createRule(string $ruleName, array $arguments = []): Rule
{
foreach ($this->rulesNamespaces as $namespace) {
try {
/** @var class-string<Rule> $name */
$name = $namespace . '\\' . ucfirst($ruleName);
$reflection = new ReflectionClass($name);
if (!$reflection->isSubclassOf(Rule::class)) {
throw new InvalidClassException(
sprintf('"%s" must be an instance of "%s"', $name, Rule::class)
);
}
if (!$reflection->isInstantiable()) {
throw new InvalidClassException(sprintf('"%s" must be instantiable', $name));
}
return $reflection->newInstanceArgs($arguments);
} catch (ReflectionException) {
continue;
}
}
throw new ComponentException(sprintf('"%s" is not a valid rule name', $ruleName));
}
}