mirror of
https://github.com/Respect/Validation.git
synced 2026-03-15 06:45:44 +01:00
85 lines
2.5 KiB
PHP
85 lines
2.5 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));
|
|
}
|
|
}
|