Passed
Push — master ( 7d85ff...c984d5 )
by Anton
01:36
created

ManyToMany::compute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 14
nc 1
nop 1
dl 0
loc 21
rs 9.7998
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
namespace Cycle\Schema\Relation;
11
12
use Cycle\ORM\Relation;
13
use Cycle\Schema\Registry;
14
use Cycle\Schema\Relation\Traits\FieldTrait;
15
use Cycle\Schema\Relation\Traits\ForeignKeyTrait;
16
17
class ManyToMany extends RelationSchema
18
{
19
    use FieldTrait, ForeignKeyTrait;
20
21
    // internal relation type
22
    protected const RELATION_TYPE = Relation::HAS_ONE;
23
24
    // relation schema options
25
    protected const RELATION_SCHEMA = [
26
        // save with parent
27
        Relation::CASCADE              => true,
28
29
        // use outer entity constrain by default
30
        Relation::CONSTRAIN            => true,
31
32
        // nullable by default
33
        Relation::NULLABLE             => true,
34
35
        // custom where condition
36
        Relation::WHERE                => [],
37
38
        // inner key of parent record will be used to fill "THOUGHT_INNER_KEY" in pivot table
39
        Relation::INNER_KEY            => '{source:primaryKey}',
40
41
        // we are going to use primary key of outer table to fill "THOUGHT_OUTER_KEY" in pivot table
42
        // this is technically "inner" key of outer record, we will name it "outer key" for simplicity
43
        Relation::OUTER_KEY            => '{target:primaryKey}',
44
45
        // name field where parent record inner key will be stored in pivot table, role + innerKey
46
        // by default
47
        Relation::THOUGHT_INNER_KEY    => '{source:role}_{innerKey}',
48
49
        // name field where inner key of outer record (outer key) will be stored in pivot table,
50
        // role + outerKey by default
51
        Relation::THOUGHT_OUTER_KEY    => '{target:role}_{outerKey}',
52
53
        // apply pivot constrain
54
        Relation::THOUGHT_CONSTRAIN    => true,
55
56
        // custom pivot where
57
        Relation::THOUGHT_WHERE        => [],
58
59
        // rendering options
60
        RelationSchema::INDEX_CREATE   => true,
61
        RelationSchema::FK_CREATE      => true,
62
        RelationSchema::FK_ACTION      => 'CASCADE',
63
        RelationSchema::BIND_INTERFACE => false
64
    ];
65
66
    /**
67
     * @param Registry $registry
68
     */
69
    public function compute(Registry $registry)
70
    {
71
        parent::compute($registry);
72
73
        $source = $registry->getEntity($this->source);
74
        $target = $registry->getEntity($this->target);
75
76
        $thought = $registry->getEntity($this->options->get(Relation::THOUGHT_ENTITY));
77
78
        $this->ensureField(
79
            $thought,
80
            $this->options->get(Relation::THOUGHT_INNER_KEY),
81
            $this->getField($source, Relation::INNER_KEY),
82
            $this->options->get(Relation::NULLABLE)
0 ignored issues
show
Bug introduced by
It seems like $this->options->get(Cycle\ORM\Relation::NULLABLE) can also be of type string; however, parameter $nullable of Cycle\Schema\Relation\ManyToMany::ensureField() does only seem to accept boolean, 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

82
            /** @scrutinizer ignore-type */ $this->options->get(Relation::NULLABLE)
Loading history...
83
        );
84
85
        $this->ensureField(
86
            $thought,
87
            $this->options->get(Relation::THOUGHT_OUTER_KEY),
88
            $this->getField($target, Relation::OUTER_KEY),
89
            $this->options->get(Relation::NULLABLE)
90
        );
91
    }
92
93
    /**
94
     * @param Registry $registry
95
     */
96
    public function render(Registry $registry)
97
    {
98
        $source = $registry->getEntity($this->source);
99
        $target = $registry->getEntity($this->target);
100
101
        $thought = $registry->getEntity($this->options->get(Relation::THOUGHT_ENTITY));
102
103
        $sourceField = $this->getField($source, Relation::INNER_KEY);
104
        $targetField = $this->getField($target, Relation::OUTER_KEY);
105
106
        $thoughtSourceField = $this->getField($thought, Relation::THOUGHT_INNER_KEY);
107
        $thoughtTargetField = $this->getField($thought, Relation::THOUGHT_OUTER_KEY);
108
109
        $table = $registry->getTableSchema($thought);
110
111
        if ($this->options->get(self::INDEX_CREATE)) {
112
            $table->index([
113
                $thoughtSourceField->getColumn(),
114
                $thoughtTargetField->getColumn()
115
            ])->unique(true);
116
        }
117
118
        if ($this->options->get(self::FK_CREATE)) {
119
            $this->createForeignKey($registry, $source, $thought, $sourceField, $thoughtSourceField);
120
            $this->createForeignKey($registry, $target, $thought, $targetField, $thoughtTargetField);
121
        }
122
    }
123
}