Passed
Push — master ( bc79a5...b222de )
by Anton
02:01
created

src/Bootloader/Cycle/SchemaBootloader.php (1 issue)

1
<?php
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
declare(strict_types=1);
9
10
namespace Spiral\Bootloader\Cycle;
11
12
use Cycle\Annotated;
13
use Cycle\ORM\RepositoryInterface;
14
use Cycle\ORM\Schema;
15
use Cycle\ORM\SchemaInterface;
16
use Cycle\ORM\Select\Repository;
17
use Cycle\Schema\Generator;
18
use Cycle\Schema\GeneratorInterface;
19
use Spiral\Boot\Bootloader\Bootloader;
20
use Spiral\Boot\Bootloader\DependedInterface;
21
use Spiral\Boot\MemoryInterface;
22
use Spiral\Bootloader\Database\DatabaseBootloader;
23
use Spiral\Bootloader\TokenizerBootloader;
24
use Spiral\Config\ConfiguratorInterface;
25
use Spiral\Core\Container;
26
use Spiral\Tokenizer\ClassesInterface;
27
28
final class SchemaBootloader extends Bootloader implements DependedInterface, Container\SingletonInterface
29
{
30
    public const BINDINGS = [
31
        SchemaInterface::class             => [self::class, 'schema'],
32
33
        // annotated entities
34
        Annotated\Entities::class          => [self::class, 'entities'],
35
        Annotated\MergeColumns::class      => [self::class, 'mergeColumns'],
36
        Annotated\MergeIndexes::class      => [self::class, 'mergeIndexes'],
37
38
        // relations
39
        Generator\GenerateRelations::class => [self::class, 'relations'],
40
    ];
41
42
    /** @var Container */
43
    private $container;
44
45
    /** @var ConfiguratorInterface */
46
    private $generators;
47
48
    /**
49
     * CycleSchemaBootloader constructor.
50
     *
51
     * @param Container $container
52
     */
53
    public function __construct(Container $container)
54
    {
55
        $this->container = $container;
56
        $this->generators = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array(Cycle\Annotated\Em...enerateTypecast::class) of type array<integer,string> is incompatible with the declared type Spiral\Config\ConfiguratorInterface of property $generators.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
57
            Annotated\Embeddings::class,
58
            Annotated\Entities::class,
59
            Generator\ResetTables::class,
60
            Annotated\MergeColumns::class,
61
            Generator\GenerateRelations::class,
62
            Generator\ValidateEntities::class,
63
            Generator\RenderTables::class,
64
            Generator\RenderRelations::class,
65
            Annotated\MergeIndexes::class,
66
            Generator\GenerateTypecast::class
67
        ];
68
    }
69
70
    /**
71
     * @param SchemaInterface|null $schema
72
     */
73
    public function boot(SchemaInterface $schema = null)
74
    {
75
        if (!is_null($schema)) {
76
            $this->bootRepositories($schema);
77
        }
78
    }
79
80
    /**
81
     * @param SchemaInterface $schema
82
     */
83
    public function bootRepositories(SchemaInterface $schema)
84
    {
85
        foreach ($schema->getRoles() as $role) {
86
            $repository = $schema->define($role, Schema::REPOSITORY);
87
            if ($repository === Repository::class || $repository === null) {
88
                // default repository can not be wired
89
                continue;
90
            }
91
92
            // initiate all repository dependencies using factory method forwarded to ORM
93
            $this->container->bind(
94
                $repository,
95
                new Container\Autowire(RepositoryInterface::class, ['role' => $role])
96
            );
97
        }
98
    }
99
100
    /**
101
     * @return array
102
     */
103
    public function defineDependencies(): array
104
    {
105
        return [
106
            TokenizerBootloader::class,
107
            DatabaseBootloader::class
108
        ];
109
    }
110
111
    /**
112
     * @param mixed $generator
113
     */
114
    public function addGenerator($generator)
115
    {
116
        $this->generators[] = $generator;
117
    }
118
119
    /**
120
     * @return GeneratorInterface[]
121
     */
122
    public function getGenerators(): array
123
    {
124
        $result = [];
125
        foreach ($this->generators as $generator) {
126
            if (is_object($generator) && !$generator instanceof Container\Autowire) {
127
                $result[] = $generator;
128
            } else {
129
                $result[] = $this->container->get($generator);
130
            }
131
        }
132
133
        return $result;
134
    }
135
136
    /**
137
     * @param MemoryInterface $memory
138
     * @return SchemaInterface|null
139
     */
140
    protected function schema(MemoryInterface $memory): ?SchemaInterface
141
    {
142
        $schema = $memory->loadData('cycle');
143
        if (is_null($schema)) {
144
            return null;
145
        }
146
147
        return new Schema($schema);
148
    }
149
150
    /**
151
     * @param ClassesInterface $classes
152
     * @return Annotated\Entities
153
     */
154
    protected function entities(ClassesInterface $classes): Annotated\Entities
155
    {
156
        return new Annotated\Entities($classes);
157
    }
158
159
    /**
160
     * @return Annotated\MergeColumns
161
     */
162
    protected function mergeColumns(): Annotated\MergeColumns
163
    {
164
        return new Annotated\MergeColumns();
165
    }
166
167
    /**
168
     * @return Annotated\MergeIndexes
169
     */
170
    protected function mergeIndexes(): Annotated\MergeIndexes
171
    {
172
        return new Annotated\MergeIndexes();
173
    }
174
175
    /**
176
     * @return Generator\GenerateRelations
177
     */
178
    protected function relations(): Generator\GenerateRelations
179
    {
180
        return new Generator\GenerateRelations();
181
    }
182
}