Test Failed
Pull Request — master (#97)
by Aleksei
02:28
created

MetadataSchemaConveyor::getEntityClassLocator()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 17
rs 9.9332
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Cycle\Schema\Conveyor;
6
7
use Cycle\Annotated\Embeddings;
8
use Cycle\Annotated\Entities;
9
use Cycle\Annotated\MergeColumns;
10
use Cycle\Annotated\MergeIndexes;
11
use JetBrains\PhpStorm\ExpectedValues;
12
use Spiral\Attributes\ReaderInterface;
13
use Spiral\Tokenizer\ClassLocator;
14
use Symfony\Component\Finder\Finder;
15
use Yiisoft\Aliases\Aliases;
16
use Yiisoft\Yii\Cycle\Exception\EmptyEntityPathsException;
17
18
abstract class MetadataSchemaConveyor extends SchemaConveyor
19
{
20
    /** @var string[] */
21
    private array $entityPaths = [];
22
23
    private int $tableNaming = Entities::TABLE_NAMING_SINGULAR;
24
25
    private bool $isAddedMetadataGenerators = false;
26
27
    final public function setTableNaming(
28
        #[ExpectedValues(valuesFromClass: Entities::class)]
29
        int $type
30
    ): void {
31
        $this->tableNaming = $type;
32
    }
33
34
    final public function getTableNaming(): int
35
    {
36
        return $this->tableNaming;
37
    }
38
39
    /**
40
     * @param string[] $paths
41
     */
42
    final public function addEntityPaths(array $paths): void
43
    {
44
        $this->entityPaths = array_merge($this->entityPaths, $paths);
45
    }
46
47
    public function getGenerators(): array
48
    {
49
        $this->addMetadataGenerators();
50
        return parent::getGenerators();
51
    }
52
53
    abstract protected function getMetadataReader(): ?ReaderInterface;
54
55
    /**
56
     * Add some generators in this conveyor into the INDEX stage
57
     * Added generators will search for entity classes and read their annotations
58
     */
59
    private function addMetadataGenerators(): void
60
    {
61
        if ($this->isAddedMetadataGenerators) {
62
            return;
63
        }
64
        $classLocator = $this->getEntityClassLocator();
65
66
        $reader = $this->getMetadataReader();
67
68
        // register embeddable entities
69
        $this->conveyor[SchemaConveyor::STAGE_INDEX][] = new Embeddings($classLocator, $reader);
70
        // register annotated entities
71
        $this->conveyor[SchemaConveyor::STAGE_INDEX][] = new Entities($classLocator, $reader, $this->tableNaming);
72
        // add @Table(columns) declarations
73
        $this->conveyor[SchemaConveyor::STAGE_INDEX][] = new MergeColumns($reader);
74
        // add @Table(indexes) declarations
75
        $this->conveyor[SchemaConveyor::STAGE_RENDER][] = new MergeIndexes($reader);
76
77
        $this->isAddedMetadataGenerators = true;
78
    }
79
80
    private function getEntityClassLocator(): ClassLocator
81
    {
82
        $aliases = $this->container->get(Aliases::class);
83
        $list = [];
84
        foreach ($this->entityPaths as $path) {
85
            $list[] = $aliases->get($path);
86
        }
87
88
        if (!count($list)) {
89
            throw new EmptyEntityPathsException();
90
        }
91
92
        $finder = (new Finder())
93
            ->files()
94
            ->in($list);
95
96
        return new ClassLocator($finder);
97
    }
98
}
99