Embeddings::run()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4.074

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 4
eloc 13
c 2
b 0
f 1
nc 4
nop 1
dl 0
loc 25
ccs 10
cts 12
cp 0.8333
crap 4.074
rs 9.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\Annotated;
6
7
use Cycle\Annotated\Annotation\Embeddable;
8
use Cycle\Annotated\Annotation\Relation\RelationInterface;
9
use Cycle\Annotated\Exception\AnnotationException;
10
use Cycle\Schema\Definition\Entity as EntitySchema;
11
use Cycle\Schema\GeneratorInterface;
12
use Cycle\Schema\Registry;
13
use Doctrine\Common\Annotations\Reader as DoctrineReader;
14
use Spiral\Attributes\ReaderInterface;
15
use Spiral\Tokenizer\ClassesInterface;
16
17
/**
18
 * Generates ORM schema based on annotated classes.
19
 */
20
final class Embeddings implements GeneratorInterface
21
{
22
    private ReaderInterface $reader;
23
24
    private Configurator $generator;
25
26 288
    public function __construct(
27
        private ClassesInterface $locator,
28
        DoctrineReader|ReaderInterface $reader = null
29
    ) {
30 288
        $this->reader = ReaderFactory::create($reader);
31 288
        $this->generator = new Configurator($this->reader);
32 288
    }
33
34 288
    public function run(Registry $registry): Registry
35
    {
36 288
        foreach ($this->locator->getClasses() as $class) {
37
            try {
38 288
                $em = $this->reader->firstClassMetadata($class, Embeddable::class);
39
            } catch (\Exception $e) {
40
                throw new AnnotationException($e->getMessage(), $e->getCode(), $e);
41
            }
42 288
            if ($em === null) {
43 288
                continue;
44
            }
45
            \assert($em instanceof Embeddable);
46
47 72
            $e = $this->generator->initEmbedding($em, $class);
48
49 72
            $this->verifyNoRelations($e, $class);
50
51
            // columns
52 72
            $this->generator->initFields($e, $class);
53
54
            // register entity (OR find parent)
55 72
            $registry->register($e);
56
        }
57
58 288
        return $registry;
59
    }
60
61 72
    public function verifyNoRelations(EntitySchema $entity, \ReflectionClass $class): void
62
    {
63 72
        foreach ($class->getProperties() as $property) {
64
            try {
65 72
                $ann = $this->reader->getPropertyMetadata($property);
66
            } catch (\Exception $e) {
67
                throw new AnnotationException($e->getMessage(), $e->getCode(), $e);
68
            }
69
70 72
            foreach ($ann as $ra) {
71 64
                if ($ra instanceof RelationInterface) {
72
                    throw new AnnotationException(
73
                        "Relations are not allowed within embeddable entities in `{$entity->getClass()}`"
74
                    );
75
                }
76
            }
77
        }
78 72
    }
79
}
80