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