Issues (20)

src/Compiler.php (3 issues)

Labels
Severity
1
<?php
2
3
/**
4
 * Cycle ORM Schema Builder.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Cycle\Schema;
13
14
use Cycle\ORM\Schema;
15
use Cycle\Schema\Definition\Entity;
16
use Doctrine\Common\Inflector\Inflector;
17
use Spiral\Database\Exception\CompilerException;
18
19
final class Compiler
20
{
21
    /** @var array */
22
    private $result = [];
23
24
    /**
25
     * Compile the registry schema.
26
     *
27
     * @param Registry             $registry
28
     * @param GeneratorInterface[] $generators
29
     * @return array
30
     *
31
     * @throws CompilerException
32
     */
33
    public function compile(Registry $registry, array $generators = []): array
34
    {
35
        foreach ($generators as $generator) {
36
            if (!$generator instanceof GeneratorInterface) {
37
                throw new CompilerException(sprintf(
38
                    'Invalid generator `%s`',
39
                    is_object($generator) ? get_class($generator) : gettype($generator)
40
                ));
41
            }
42
43
            $registry = $generator->run($registry);
44
        }
45
46
        foreach ($registry->getIterator() as $entity) {
47
            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...
48
                // incomplete entity, skip
49
                continue;
50
            }
51
52
            $this->compute($registry, $entity);
53
        }
54
55
        return $this->result;
56
    }
57
58
    /**
59
     * Get compiled schema result.
60
     *
61
     * @return array
62
     */
63
    public function getSchema(): array
64
    {
65
        return $this->result;
66
    }
67
68
    /**
69
     * Compile entity and relation definitions into packed ORM schema.
70
     *
71
     * @param Registry $registry
72
     * @param Entity   $entity
73
     */
74
    protected function compute(Registry $registry, Entity $entity): void
75
    {
76
        $schema = [
77
            Schema::ENTITY       => $entity->getClass(),
78
            Schema::SOURCE       => $entity->getSource(),
79
            Schema::MAPPER       => $entity->getMapper(),
80
            Schema::REPOSITORY   => $entity->getRepository(),
81
            Schema::CONSTRAIN    => $entity->getConstrain(),
82
            Schema::SCHEMA       => $entity->getSchema(),
83
            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...
84
            Schema::COLUMNS      => $this->renderColumns($entity),
85
            Schema::FIND_BY_KEYS => $this->renderReferences($entity),
86
            Schema::TYPECAST     => $this->renderTypecast($entity),
87
            Schema::RELATIONS    => $this->renderRelations($registry, $entity)
88
        ];
89
90
        if ($registry->hasTable($entity)) {
91
            $schema[Schema::DATABASE] = $registry->getDatabase($entity);
92
            $schema[Schema::TABLE] = $registry->getTable($entity);
93
        }
94
95
        // table inheritance
96
        foreach ($registry->getChildren($entity) as $child) {
97
            $this->result[$child->getClass()] = [Schema::ROLE => $entity->getRole()];
98
            $schema[Schema::CHILDREN][$this->childAlias($child)] = $child->getClass();
99
        }
100
101
        ksort($schema);
102
        $this->result[$entity->getRole()] = $schema;
103
    }
104
105
    /**
106
     * @param Entity $entity
107
     * @return array
108
     */
109
    protected function renderColumns(Entity $entity): array
110
    {
111
        $schema = [];
112
        foreach ($entity->getFields() as $name => $field) {
113
            $schema[$name] = $field->getColumn();
114
        }
115
116
        return $schema;
117
    }
118
119
    /**
120
     * @param Entity $entity
121
     * @return array
122
     */
123
    protected function renderTypecast(Entity $entity): array
124
    {
125
        $schema = [];
126
        foreach ($entity->getFields() as $name => $field) {
127
            if ($field->hasTypecast()) {
128
                $schema[$name] = $field->getTypecast();
129
            }
130
        }
131
132
        return $schema;
133
    }
134
135
    /**
136
     * @param Entity $entity
137
     * @return array
138
     */
139
    protected function renderReferences(Entity $entity): array
140
    {
141
        $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...
142
143
        foreach ($entity->getFields() as $name => $field) {
144
            if ($field->isReferenced()) {
145
                $schema[] = $name;
146
            }
147
        }
148
149
        return array_unique($schema);
150
    }
151
152
    /**
153
     * @param Registry $registry
154
     * @param Entity   $entity
155
     * @return array
156
     */
157
    protected function renderRelations(Registry $registry, Entity $entity): array
158
    {
159
        $result = [];
160
        foreach ($registry->getRelations($entity) as $name => $relation) {
161
            $result[$name] = $relation->packSchema();
162
        }
163
164
        return $result;
165
    }
166
167
    /**
168
     * @param Entity $entity
169
     * @return string|null
170
     */
171
    protected function getPrimary(Entity $entity): ?string
172
    {
173
        foreach ($entity->getFields() as $name => $field) {
174
            if ($field->isPrimary()) {
175
                return $name;
176
            }
177
        }
178
179
        return null;
180
    }
181
182
    /**
183
     * Return the unique alias for the child entity.
184
     *
185
     * @param Entity $entity
186
     * @return string
187
     */
188
    protected function childAlias(Entity $entity): string
189
    {
190
        $r = new \ReflectionClass($entity->getClass());
191
        return Inflector::classify($r->getShortName());
192
    }
193
}
194