Passed
Push — master ( 1e6bc1...7a1c1c )
by Anton
04:14
created

MergeIndexes::mapColumns()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 13
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php declare(strict_types=1);
2
/**
3
 * Spiral Framework.
4
 *
5
 * @license   MIT
6
 * @author    Anton Titov (Wolfy-J)
7
 */
8
9
namespace Cycle\Annotated;
10
11
use Cycle\Annotated\Annotation\Table;
12
use Cycle\Schema\Definition\Entity;
13
use Cycle\Schema\GeneratorInterface;
14
use Cycle\Schema\Registry;
15
use Spiral\Annotations\Parser;
16
use Spiral\Database\Schema\AbstractTable;
17
18
final class MergeIndexes implements GeneratorInterface
19
{
20
    /** @var Parser */
21
    private $parser;
22
23
    /**
24
     * @param Parser|null $parser
25
     */
26
    public function __construct(Parser $parser = null)
27
    {
28
        $this->parser = $parser ?? Generator::getDefaultParser();
29
    }
30
31
    /**
32
     * @param Registry $registry
33
     * @return Registry
34
     */
35
    public function run(Registry $registry): Registry
36
    {
37
        foreach ($registry as $e) {
38
            if ($e->getClass() === null || !$registry->hasTable($e)) {
39
                continue;
40
            }
41
42
            $this->render($registry->getTableSchema($e), $e, $e->getClass());
43
44
            // copy table declarations from related classes
45
            $this->render($registry->getTableSchema($e), $e, $e->getMapper());
46
            $this->render($registry->getTableSchema($e), $e, $e->getRepository());
47
            $this->render($registry->getTableSchema($e), $e, $e->getSource());
48
            $this->render($registry->getTableSchema($e), $e, $e->getConstrain());
49
50
            foreach ($registry->getChildren($e) as $child) {
51
                $this->render($registry->getTableSchema($e), $e, $child->getClass());
52
            }
53
        }
54
55
        return $registry;
56
    }
57
58
    /**
59
     * @param AbstractTable $table
60
     * @param Entity        $entity
61
     * @param string|null   $class
62
     */
63
    protected function render(AbstractTable $table, Entity $entity, ?string $class)
64
    {
65
        if ($class === null) {
66
            return;
67
        }
68
69
        try {
70
            $class = new \ReflectionClass($class);
71
        } catch (\ReflectionException $e) {
72
            return;
73
        }
74
75
        if ($class->getDocComment() === false) {
76
            return;
77
        }
78
79
        $ann = $this->parser->parse($class->getDocComment());
0 ignored issues
show
Bug introduced by Wolfy-J
It seems like $class->getDocComment() can also be of type true; however, parameter $body of Spiral\Annotations\Parser::parse() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

79
        $ann = $this->parser->parse(/** @scrutinizer ignore-type */ $class->getDocComment());
Loading history...
80
        if (!isset($ann[Table::NAME])) {
81
            return;
82
        }
83
84
        /** @var Table $ta */
85
        $ta = $ann[Table::NAME];
86
87
        $this->renderIndexes($table, $entity, $ta->getIndexes());
88
    }
89
90
    /**
91
     * @param AbstractTable $table
92
     * @param Entity        $entity
93
     * @param Table\Index[] $indexes
94
     */
95
    public function renderIndexes(AbstractTable $table, Entity $entity, array $indexes)
96
    {
97
        foreach ($indexes as $index) {
98
            if ($index->getColumns() === []) {
99
                continue;
100
            }
101
102
            $columns = $this->mapColumns($entity, $index->getColumns());
103
104
            $indexSchema = $table->index($columns);
105
            $indexSchema->unique($index->isUnique());
106
107
            if ($index->getIndex() !== null) {
108
                $indexSchema->setName($index->getIndex());
109
            }
110
        }
111
    }
112
113
    /**
114
     * @param Entity $entity
115
     * @param array  $columns
116
     * @return array
117
     */
118
    protected function mapColumns(Entity $entity, array $columns): array
119
    {
120
        $result = [];
121
122
        foreach ($columns as $column) {
123
            if ($entity->getFields()->has($column)) {
124
                $result[] = $entity->getFields()->get($column)->getColumn();
125
            } else {
126
                $result[] = $column;
127
            }
128
        }
129
130
        return $result;
131
    }
132
}