Passed
Push — 3.x ( 080893...4e5cb3 )
by Aleksei
09:48
created

Embeddings::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 1
rs 10
c 1
b 0
f 1
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 96
    public function __construct(
27
        private ClassesInterface $locator,
28
        DoctrineReader|ReaderInterface $reader = null
29
    ) {
30 96
        $this->reader = ReaderFactory::create($reader);
31 96
        $this->generator = new Configurator($this->reader);
32 96
    }
33
34 96
    public function run(Registry $registry): Registry
35
    {
36 96
        foreach ($this->locator->getClasses() as $class) {
37
            try {
38 96
                $em = $this->reader->firstClassMetadata($class, Embeddable::class);
39
            } catch (\Exception $e) {
40
                throw new AnnotationException($e->getMessage(), $e->getCode(), $e);
41
            }
42 96
            if ($em === null) {
43 96
                continue;
44
            }
45
46 24
            $e = $this->generator->initEmbedding($em, $class);
47
48 24
            $this->verifyNoRelations($e, $class);
49
50
            // columns
51 24
            $this->generator->initFields($e, $class, $em->getColumnPrefix());
52
53
            // register entity (OR find parent)
54 24
            $registry->register($e);
55
        }
56
57 96
        return $registry;
58
    }
59
60 24
    public function verifyNoRelations(EntitySchema $entity, \ReflectionClass $class): void
61
    {
62 24
        foreach ($class->getProperties() as $property) {
63
            try {
64 24
                $ann = $this->reader->getPropertyMetadata($property);
65
            } catch (\Exception $e) {
66
                throw new AnnotationException($e->getMessage(), $e->getCode(), $e);
67
            }
68
69 24
            foreach ($ann as $ra) {
70 16
                if ($ra instanceof RelationInterface) {
71
                    throw new AnnotationException(
72
                        "Relations are not allowed within embeddable entities in `{$entity->getClass()}`"
73
                    );
74
                }
75
            }
76
        }
77 24
    }
78
}
79