Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
64.52% covered (warning)
64.52%
20 / 31
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
IdentifierUri
64.52% covered (warning)
64.52%
20 / 31
50.00% covered (danger)
50.00%
2 / 4
22.76
0.00% covered (danger)
0.00%
0 / 1
 validate
37.50% covered (danger)
37.50%
3 / 8
0.00% covered (danger)
0.00%
0 / 1
7.91
 split
62.50% covered (warning)
62.50%
10 / 16
0.00% covered (danger)
0.00%
0 / 1
9.58
 getRegularExpression
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 createRandom
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace Apie\Core\ValueObjects;
4
5use Apie\Core\ApieLib;
6use Apie\Core\Attributes\FakeMethod;
7use Apie\Core\Entities\EntityInterface;
8use Apie\Core\Identifiers\IdentifierInterface;
9use Apie\Core\IdentifierUtils;
10use Apie\Core\RegexUtils;
11use Apie\Core\Utils\ConverterUtils;
12use Apie\Core\ValueObjects\Exceptions\InvalidStringForValueObjectException;
13use Apie\Core\ValueObjects\Interfaces\HasRegexValueObjectInterface;
14use Apie\TypeConverter\ReflectionTypeFactory;
15use Faker\Generator;
16
17#[FakeMethod('createRandom')]
18class IdentifierUri implements HasRegexValueObjectInterface
19{
20    use IsStringWithRegexValueObject;
21
22    public static function validate(string $input): void
23    {
24        if (!preg_match(static::getRegularExpression(), $input)) {
25            throw new InvalidStringForValueObjectException(
26                $input,
27                new \ReflectionClass(self::class)
28            );
29        }
30        if (ApieLib::hasAlias(EntityInterface::class)) {
31            if (null === self::split($input)) {
32                throw new InvalidStringForValueObjectException($input, new \ReflectionClass(self::class));
33            }
34        }
35    }
36
37    /**
38     * @return array{class-string<EntityInterface>, IdentifierInterface<EntityInterface>}|null
39     */
40    private static function split(string $input): ?array
41    {
42        $alias = ReflectionTypeFactory::createReflectionType(ApieLib::getAlias(EntityInterface::class));
43        $split = explode('/', $input, 2);
44        assert(count($split) === 2);
45        if ($alias instanceof \ReflectionNamedType) {
46            $class = ConverterUtils::toReflectionClass($alias->getName());
47            if ($class && $class->getShortName() === $split[0]) {
48                $identifier = ConverterUtils::toReflectionClass($class->getMethod('getId')->getReturnType());
49                return [$class->name, $identifier->getMethod('fromNative')->invoke(null, $split[1])];
50            }
51            return null;
52        }
53        assert($alias instanceof \ReflectionUnionType);
54        foreach ($alias->getTypes() as $type) {
55            $class = ConverterUtils::toReflectionClass($type);
56            if ($class && $class->getShortName() === $split[0]) {
57                $identifier = ConverterUtils::toReflectionClass($class->getMethod('getId')->getReturnType());
58                return [$class->name, $identifier->getMethod('fromNative')->invoke(null, $split[1])];
59            }
60        }
61        return null;
62    }
63
64    public static function getRegularExpression(): string
65    {
66        // if (!ApieLib::hasAlias(EntityInterface::class)) {
67        return '/^[A-Z][a-zA-Z0-9]*\/[a-zA-Z0-9_-]+$/';
68        /*}
69        $regex = [];
70        $alias = ReflectionTypeFactory::createReflectionType(ApieLib::getAlias(EntityInterface::class));
71        $types = $alias instanceof \ReflectionNamedType ? [$alias] : $alias->getTypes();
72        foreach ($types as $type) {
73            $class = ConverterUtils::toReflectionClass($type);
74            if ($class) {
75                $identifier = ConverterUtils::toReflectionClass($class->getMethod('getId')->getReturnType());
76                if (in_array(HasRegexValueObjectInterface::class, $identifier->getInterfaceNames())) {
77                    $regex[] = $class->getShortName()
78                        . '/'
79                        . RegexUtils::removeDelimiters(
80                            $identifier->getMethod('getRegularExpression')->invoke(null)
81                        );
82                } else {
83                    $regex[] = $class->getShortName() . '/.+';
84                }
85            }
86        }
87        return '#^(' . implode(')|(', $regex) . ')$#';*/
88    }
89
90    public static function createRandom(Generator $faker): self
91    {
92        $alias = ReflectionTypeFactory::createReflectionType(ApieLib::getAlias(EntityInterface::class));
93        // @phpstan-ignore method.notFound
94        $types = $alias instanceof \ReflectionNamedType ? [$alias] : $alias->getTypes();
95        $entityClass = ConverterUtils::toReflectionClass($faker->randomElement($types));
96        $identifierClass = IdentifierUtils::entityClassToIdentifier($entityClass);
97        $identifier = $faker->fakeClass($identifierClass->name);
98        return new self($entityClass->getShortName() . '/' . $identifier->toNative());
99    }
100}