refactor rules out of DataObject
This commit is contained in:
parent
77d1aebc0a
commit
74f151df07
5 changed files with 115 additions and 93 deletions
|
|
@ -5,9 +5,12 @@ declare(strict_types=1);
|
|||
namespace Icefox\DTO\Support;
|
||||
|
||||
use Icefox\DTO\Attributes\CastWith;
|
||||
use Icefox\DTO\Attributes\OverwriteRules;
|
||||
use Icefox\DTO\Config;
|
||||
use Icefox\DTO\Attributes\FromMapper;
|
||||
use Icefox\DTO\Log;
|
||||
use Icefox\DTO\ParameterMeta;
|
||||
use Icefox\DTO\ReflectionHelper;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Validation\Rule;
|
||||
use ReflectionClass;
|
||||
|
|
@ -29,8 +32,6 @@ use phpDocumentor\Reflection\Types\Object_;
|
|||
|
||||
class RuleFactory
|
||||
{
|
||||
protected static array $cache = [];
|
||||
|
||||
/**
|
||||
* @return array<string, array<string|Rule>>
|
||||
*/
|
||||
|
|
@ -57,7 +58,7 @@ class RuleFactory
|
|||
} elseif ($type instanceof Float_ || $type instanceof Integer) {
|
||||
$rules[$prefix][] = 'numeric';
|
||||
} elseif ($type instanceof Object_) {
|
||||
$paramsSub = self::getParametersMeta($type->getFqsen()->__toString());
|
||||
$paramsSub = ReflectionHelper::getParametersMeta($type->getFqsen()->__toString());
|
||||
$rules = array_merge(
|
||||
$rules,
|
||||
self::infer($paramsSub, $prefix . '.'),
|
||||
|
|
@ -66,39 +67,6 @@ class RuleFactory
|
|||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param class-string $class
|
||||
* @return array<ParameterMeta>
|
||||
*/
|
||||
public static function getParametersMeta(string $class): array
|
||||
{
|
||||
if (array_key_exists($class, self::$cache)) {
|
||||
return self::$cache[$class];
|
||||
}
|
||||
|
||||
$reflection = new ReflectionClass($class);
|
||||
$constructor = $reflection->getConstructor();
|
||||
try {
|
||||
$docblockParams = (DocBlockFactory::createInstance())->create(
|
||||
$constructor->getDocComment(),
|
||||
(new ContextFactory())->createFromReflector($constructor),
|
||||
)->getTagsByName('param');
|
||||
} catch (\Exception) {
|
||||
$docblockParams = [];
|
||||
}
|
||||
self::$cache[$class] = array_map(
|
||||
fn(ReflectionParameter $p) => new ParameterMeta(
|
||||
$p,
|
||||
array_find(
|
||||
$docblockParams,
|
||||
fn(Tag $tag) => $tag instanceof Param ? $tag->getVariableName() == $p->getName() : false,
|
||||
),
|
||||
),
|
||||
$constructor->getParameters(),
|
||||
);
|
||||
return self::$cache[$class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<ParameterMeta> $parameters
|
||||
* @return array<string,array<int,string|Rule>>
|
||||
|
|
@ -160,7 +128,7 @@ class RuleFactory
|
|||
$rules[$root][] = Rule::enum($name);
|
||||
}
|
||||
} else {
|
||||
$paramsSub = self::getParametersMeta($type->getName());
|
||||
$paramsSub = ReflectionHelper::getParametersMeta($type->getName());
|
||||
$rules = array_merge(
|
||||
$rules,
|
||||
self::infer($paramsSub, $root . '.'),
|
||||
|
|
@ -190,4 +158,48 @@ class RuleFactory
|
|||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function __construct(public Log $log) {}
|
||||
|
||||
/**
|
||||
* @param class-string $class
|
||||
* @return array<string,array<int, string>>
|
||||
*/
|
||||
public function make(string $class): array
|
||||
{
|
||||
$parameters = ReflectionHelper::getParametersMeta($class);
|
||||
|
||||
$classReflection = new ReflectionClass($class);
|
||||
$hasRulesMethod = $classReflection->hasMethod('rules');
|
||||
|
||||
$customRules = $hasRulesMethod ? App::call("$class::rules", []) : [];
|
||||
|
||||
|
||||
if ($hasRulesMethod && !empty($classReflection->getMethod('rules')->getAttributes(OverwriteRules::class))) {
|
||||
$rules = $customRules;
|
||||
} else {
|
||||
$inferredRules = RuleFactory::infer($parameters, '');
|
||||
$rules = self::mergeRules($inferredRules, $customRules);
|
||||
}
|
||||
$this->log->rules($rules);
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,array<int, string>> $inferredRules
|
||||
* @param array<string,array<int, string>> $customRules
|
||||
* @return array<string,array<int, string>>
|
||||
*/
|
||||
protected function mergeRules(array $inferredRules, array $customRules): array
|
||||
{
|
||||
$merged = $inferredRules;
|
||||
foreach ($customRules as $key => $rules) {
|
||||
if (isset($merged[$key])) {
|
||||
$merged[$key] = array_values(array_unique(array_merge($merged[$key], $rules)));
|
||||
} else {
|
||||
$merged[$key] = $rules;
|
||||
}
|
||||
}
|
||||
return $merged;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue