Passed
Push — master ( 2fd976...262699 )
by Anton
01:57
created

AbstractSchema::withContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 4
dl 0
loc 13
rs 10
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\Schema\Definition\Entity;
13
use Cycle\Schema\Exception\BuilderException;
14
use Cycle\Schema\Registry;
15
use Cycle\Schema\Relation\Util\OptionRouter;
16
use Cycle\Schema\RelationInterface;
17
18
abstract class AbstractSchema implements RelationInterface
19
{
20
    // name of all required relation options
21
    protected const OPTION_SCHEMA = [];
22
23
    /** @var string */
24
    protected $source;
25
26
    /** @var string */
27
    protected $target;
28
29
    /** @var OptionRouter */
30
    protected $options;
31
32
    /**
33
     * @inheritdoc
34
     */
35
    public function withContext(string $name, string $source, string $target, OptionRouter $options): RelationInterface
36
    {
37
        $relation = clone $this;
38
        $relation->source = $source;
39
        $relation->target = $target;
40
41
        $relation->options = $options->withTemplate(static::OPTION_SCHEMA)->withContext([
42
            'relation'    => $name,
43
            'source:role' => $source,
44
            'target:role' => $target
45
        ]);
46
47
        return $relation;
48
    }
49
50
    /**
51
     * @param Registry $registry
52
     */
53
    public function compute(Registry $registry)
54
    {
55
        $this->options = $this->options->withContext([
56
            'source:primaryKey' => $this->getPrimary($registry->getEntity($this->source))
57
        ]);
58
59
        if ($registry->hasRole($this->target)) {
60
            $this->options = $this->options->withContext([
61
                'target:primaryKey' => $this->getPrimary($registry->getEntity($this->target))
62
            ]);
63
        }
64
    }
65
66
    /**
67
     * @param Entity $entity
68
     * @return string
69
     *
70
     * @throws BuilderException
71
     */
72
    private function getPrimary(Entity $entity): string
73
    {
74
        foreach ($entity->getFields() as $name => $field) {
75
            if ($field->isPrimary()) {
76
                return $name;
77
            }
78
        }
79
80
        throw new BuilderException("Entity `{$entity->getRole()}` must have defined primary key");
81
    }
82
}