Passed
Push — master ( 1fa407...e70c1d )
by Anton
04:02
created

src/Compiler.php (3 issues)

Labels
Severity
1
<?php
2
/**
3
 * Cycle ORM Schema Builder.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
declare(strict_types=1);
9
10
namespace Cycle\Schema;
11
12
use Cycle\ORM\Schema;
13
use Cycle\Schema\Definition\Entity;
14
use Doctrine\Common\Inflector\Inflector;
15
use Spiral\Database\Exception\CompilerException;
16
17
final class Compiler
18
{
19
    /** @var array */
20
    private $result = [];
21
22
    /**
23
     * Compile the registry schema.
24
     *
25
     * @param Registry             $registry
26
     * @param GeneratorInterface[] $generators
27
     * @return array
28
     *
29
     * @throws CompilerException
30
     */
31
    public function compile(Registry $registry, array $generators = []): array
32
    {
33
        foreach ($generators as $generator) {
34
            if (!$generator instanceof GeneratorInterface) {
35
                throw new CompilerException(sprintf(
36
                    "Invalid generator `%s`",
37
                    is_object($generator) ? get_class($generator) : gettype($generator)
38
                ));
39
            }
40
41
            $registry = $generator->run($registry);
42
        }
43
44
        foreach ($registry->getIterator() as $entity) {
45
            if ($this->getPrimary($entity) === null) {
0 ignored issues
show
Are you sure the usage of $this->getPrimary($entity) targeting Cycle\Schema\Compiler::getPrimary() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
46
                // incomplete entity, skip
47
                continue;
48
            }
49
50
            $this->compute($registry, $entity);
51
        }
52
53
        return $this->result;
54
    }
55
56
    /**
57
     * Get compiled schema result.
58
     *
59
     * @return array
60
     */
61
    public function getSchema(): array
62
    {
63
        return $this->result;
64
    }
65
66
    /**
67
     * Compile entity and relation definitions into packed ORM schema.
68
     *
69
     * @param Registry $registry
70
     * @param Entity   $entity
71
     */
72
    protected function compute(Registry $registry, Entity $entity)
73
    {
74
        $schema = [
75
            Schema::ENTITY       => $entity->getClass(),
76
            Schema::SOURCE       => $entity->getSource(),
77
            Schema::MAPPER       => $entity->getMapper(),
78
            Schema::REPOSITORY   => $entity->getRepository(),
79
            Schema::CONSTRAIN    => $entity->getConstrain(),
80
            Schema::SCHEMA       => $entity->getSchema(),
81
            Schema::PRIMARY_KEY  => $this->getPrimary($entity),
0 ignored issues
show
Are you sure the usage of $this->getPrimary($entity) targeting Cycle\Schema\Compiler::getPrimary() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
82
            Schema::COLUMNS      => $this->renderColumns($entity),
83
            Schema::FIND_BY_KEYS => $this->renderReferences($entity),
84
            Schema::TYPECAST     => $this->renderTypecast($entity),
85
            Schema::RELATIONS    => $this->renderRelations($registry, $entity)
86
        ];
87
88
        if ($registry->hasTable($entity)) {
89
            $schema[Schema::DATABASE] = $registry->getDatabase($entity);
90
            $schema[Schema::TABLE] = $registry->getTable($entity);
91
        }
92
93
        // table inheritance
94
        foreach ($registry->getChildren($entity) as $child) {
95
            $this->result[$child->getClass()] = [Schema::ROLE => $entity->getRole()];
96
            $schema[Schema::CHILDREN][$this->childAlias($child)] = $child->getClass();
97
        }
98
99
        ksort($schema);
100
        $this->result[$entity->getRole()] = $schema;
101
    }
102
103
    /**
104
     * @param Entity $entity
105
     * @return array
106
     */
107
    protected function renderColumns(Entity $entity): array
108
    {
109
        $schema = [];
110
        foreach ($entity->getFields() as $name => $field) {
111
            $schema[$name] = $field->getColumn();
112
        }
113
114
        return $schema;
115
    }
116
117
    /**
118
     * @param Entity $entity
119
     * @return array
120
     */
121
    protected function renderTypecast(Entity $entity): array
122
    {
123
        $schema = [];
124
        foreach ($entity->getFields() as $name => $field) {
125
            if ($field->hasTypecast()) {
126
                $schema[$name] = $field->getTypecast();
127
            }
128
        }
129
130
        return $schema;
131
    }
132
133
    /**
134
     * @param Entity $entity
135
     * @return array
136
     */
137
    protected function renderReferences(Entity $entity): array
138
    {
139
        $schema = [$this->getPrimary($entity)];
0 ignored issues
show
Are you sure the usage of $this->getPrimary($entity) targeting Cycle\Schema\Compiler::getPrimary() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
140
141
        foreach ($entity->getFields() as $name => $field) {
142
            if ($field->isReferenced()) {
143
                $schema[] = $name;
144
            }
145
        }
146
147
        return array_unique($schema);
148
    }
149
150
    /**
151
     * @param Registry $registry
152
     * @param Entity   $entity
153
     * @return array
154
     */
155
    protected function renderRelations(Registry $registry, Entity $entity): array
156
    {
157
        $result = [];
158
        foreach ($registry->getRelations($entity) as $name => $relation) {
159
            $result[$name] = $relation->packSchema();
160
        }
161
162
        return $result;
163
    }
164
165
    /**
166
     * @param Entity $entity
167
     * @return string|null
168
     */
169
    protected function getPrimary(Entity $entity): ?string
170
    {
171
        foreach ($entity->getFields() as $name => $field) {
172
            if ($field->isPrimary()) {
173
                return $name;
174
            }
175
        }
176
177
        return null;
178
    }
179
180
    /**
181
     * Return the unique alias for the child entity.
182
     *
183
     * @param Entity $entity
184
     * @return string
185
     */
186
    protected function childAlias(Entity $entity): string
187
    {
188
        $r = new \ReflectionClass($entity->getClass());
189
        return Inflector::classify($r->getShortName());
190
    }
191
}