Passed
Push — master ( 871390...4cb0ab )
by Anton
02:03
created

RefersTo::render()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 4
nop 1
dl 0
loc 16
rs 9.9666
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
/**
18
 * Similar to BelongsTo relation but does not force external object to always exists.
19
 */
20
class RefersTo extends RelationSchema
21
{
22
    use FieldTrait, ForeignKeyTrait;
23
24
    // internal relation type
25
    protected const RELATION_TYPE = Relation::REFERS_TO;
26
27
    // relation schema options
28
    protected const RELATION_SCHEMA = [
29
        // save with parent
30
        Relation::CASCADE              => true,
31
32
        // use outer entity constrain by default
33
        Relation::CONSTRAIN            => true,
34
35
        // nullable by default
36
        Relation::NULLABLE             => true,
37
38
        // link to parent entity primary key by default
39
        Relation::INNER_KEY            => '{relation}_{outerKey}',
40
41
        // default field name for inner key
42
        Relation::OUTER_KEY            => '{target:primaryKey}',
43
44
        // rendering options
45
        RelationSchema::INDEX_CREATE   => true,
46
        RelationSchema::FK_CREATE      => true,
47
        RelationSchema::FK_ACTION      => 'SET NULL',
48
        RelationSchema::BIND_INTERFACE => false
49
    ];
50
51
    /**
52
     * @param Registry $registry
53
     */
54
    public function compute(Registry $registry)
55
    {
56
        parent::compute($registry);
57
58
        $source = $registry->getEntity($this->source);
59
        $target = $registry->getEntity($this->target);
60
61
        // create target outer field
62
        $this->ensureField(
63
            $source,
64
            $this->options->get(Relation::INNER_KEY),
65
            $this->getField($target, Relation::OUTER_KEY)
66
        );
67
    }
68
69
    /**
70
     * @param Registry $registry
71
     */
72
    public function render(Registry $registry)
73
    {
74
        $source = $registry->getEntity($this->source);
75
        $target = $registry->getEntity($this->target);
76
77
        $innerField = $this->getField($source, Relation::INNER_KEY);
78
        $outerField = $this->getField($target, Relation::OUTER_KEY);
79
80
        $table = $registry->getTableSchema($source);
81
82
        if ($this->options->get(self::INDEX_CREATE)) {
83
            $table->index([$innerField->getColumn()]);
84
        }
85
86
        if ($this->options->get(self::FK_CREATE)) {
87
            $this->createForeignKey($registry, $target, $source, $outerField, $innerField);
88
        }
89
    }
90
}