ResolveInterfaces   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Test Coverage

Coverage 85.19%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 30
dl 0
loc 72
ccs 23
cts 27
cp 0.8519
rs 10
c 1
b 0
f 0
wmc 15

3 Methods

Rating   Name   Duplication   Size   Complexity  
A compute() 0 15 4
A run() 0 7 2
B resolve() 0 32 9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\Schema\Generator;
6
7
use Cycle\Schema\Definition\Entity;
8
use Cycle\Schema\Exception\RegistryException;
9
use Cycle\Schema\Exception\RelationException;
10
use Cycle\Schema\GeneratorInterface;
11
use Cycle\Schema\Registry;
12
13
final class ResolveInterfaces implements GeneratorInterface
14
{
15
    // option to indicate that static link resolution is required
16
    public const STATIC_LINK = 'staticLink';
17
18
    public function run(Registry $registry): Registry
19
    {
20
        foreach ($registry as $entity) {
21
            $this->compute($registry, $entity);
22
        }
23 48
24
        return $registry;
25 48
    }
26 48
27
    /**
28
     *
29 24
     * @throws RelationException
30
     */
31
    protected function compute(Registry $registry, Entity $entity): void
32
    {
33
        foreach ($entity->getRelations() as $relation) {
34
            if (!$relation->getOptions()->has(self::STATIC_LINK)) {
35
                continue;
36
            }
37
38 48
            $target = $relation->getTarget();
39
            if ($registry->hasEntity($target)) {
40 48
                // no need to resolve
41 48
                continue;
42 16
            }
43
44
            $relation->setTarget($this->resolve($registry, $target));
45 32
            $relation->getOptions()->remove(self::STATIC_LINK);
46 32
        }
47
    }
48
49
    /**
50
     *
51 32
     * @return non-empty-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
52 8
     */
53
    protected function resolve(Registry $registry, string $target): string
54 24
    {
55
        if (!interface_exists($target)) {
56
            throw new RelationException("Unable to resolve static link to non interface target `{$target}`");
57
        }
58
59
        $found = null;
60
        foreach ($registry->getIterator() as $entity) {
61
            if ($entity->getClass() === null) {
62 32
                continue;
63
            }
64 32
65 8
            try {
66
                $candidate = new \ReflectionClass($entity->getClass());
67
            } catch (\ReflectionException $e) {
68 24
                throw new RegistryException($e->getMessage(), $e->getCode(), $e);
69 24
            }
70 24
71
            if ($candidate->isSubclassOf($target) || $candidate->implementsInterface($target)) {
72
                if ($found !== null) {
73
                    throw new RelationException("Ambiguous static link to `{$target}`");
74
                }
75 24
76
                $found = $entity->getClass();
77
            }
78
        }
79
80 24
        if ($found !== null) {
81 16
            return $found;
82 8
        }
83
84
        throw new RelationException("Unable to resolve static link to `{$target}`");
85 16
    }
86
}
87