Passed
Push — master ( c93c78...d9ab06 )
by Anton
04:33 queued 02:57
created

src/Embeddings.php (1 issue)

Labels
Severity
1
<?php declare(strict_types=1);
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Cycle\Annotated;
10
11
use Cycle\Annotated\Annotation\Embeddable;
12
use Cycle\Annotated\Annotation\Relation\RelationInterface;
13
use Cycle\Annotated\Exception\AnnotationException;
14
use Cycle\Schema\Definition\Entity as EntitySchema;
15
use Cycle\Schema\GeneratorInterface;
16
use Cycle\Schema\Registry;
17
use Spiral\Annotations\Parser;
18
use Spiral\Tokenizer\ClassesInterface;
19
20
/**
21
 * Generates ORM schema based on annotated classes.
22
 */
23
final class Embeddings implements GeneratorInterface
24
{
25
    /** @var ClassesInterface */
26
    private $locator;
27
28
    /** @var Parser */
29
    private $parser;
30
31
    /** @var Generator */
32
    private $generator;
33
34
    /**
35
     * @param ClassesInterface $locator
36
     * @param Parser|null      $parser
37
     */
38
    public function __construct(ClassesInterface $locator, Parser $parser = null)
39
    {
40
        $this->locator = $locator;
41
        $this->parser = $parser ?? Generator::getDefaultParser();
42
        $this->generator = new Generator($this->parser);
43
    }
44
45
    /**
46
     * @param Registry $registry
47
     * @return Registry
48
     */
49
    public function run(Registry $registry): Registry
50
    {
51
        foreach ($this->locator->getClasses() as $class) {
52
            if ($class->getDocComment() === false) {
53
                continue;
54
            }
55
56
            $ann = $this->parser->parse($class->getDocComment());
57
            if (!isset($ann[Embeddable::NAME])) {
58
                continue;
59
            }
60
61
            /** @var Embeddable $em */
62
            $em = $ann[Embeddable::NAME];
63
64
            $e = $this->generator->initEmbedding($em, $class);
65
66
            $this->verifyNoRelations($e, $class);
67
68
            // columns
69
            $this->generator->initFields($e, $class, $em->getColumnPrefix());
70
71
            // register entity (OR find parent)
72
            $registry->register($e);
73
        }
74
75
        return $registry;
76
    }
77
78
    /**
79
     * @param EntitySchema     $entity
80
     * @param \ReflectionClass $class
81
     */
82
    public function verifyNoRelations(EntitySchema $entity, \ReflectionClass $class)
83
    {
84
        foreach ($class->getProperties() as $property) {
85
            if ($property->getDocComment() === false) {
86
                continue;
87
            }
88
89
            $ann = $this->parser->parse($property->getDocComment());
0 ignored issues
show
It seems like $property->getDocComment() can also be of type true; however, parameter $body of Spiral\Annotations\Parser::parse() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

89
            $ann = $this->parser->parse(/** @scrutinizer ignore-type */ $property->getDocComment());
Loading history...
90
91
            foreach ($ann as $ra) {
92
                if ($ra instanceof RelationInterface) {
93
                    throw new AnnotationException(
94
                        "Relations are not allowed within embeddable entities in `{$entity->getClass()}`"
95
                    );
96
                }
97
            }
98
        }
99
    }
100
}
101
102