Passed
Pull Request — master (#97)
by Aleksei
03:27
created

CompositedSchemaConveyor::getMetadataReader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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