Passed
Push — master ( ae25c0...fd0368 )
by Anton
01:32
created

RelationGenerator::compute()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 2
dl 0
loc 14
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\Generator;
11
12
use Cycle\ORM\Relation;
13
use Cycle\Schema\Definition\Entity;
14
use Cycle\Schema\Exception\BuilderException;
15
use Cycle\Schema\Generator\Relation\OptionMapper;
16
use Cycle\Schema\GeneratorInterface;
17
use Cycle\Schema\Registry;
18
use Cycle\Schema\RelationInterface;
19
20
/**
21
 * Generate relations based on their schematic definitions.
22
 */
23
class RelationGenerator implements GeneratorInterface
24
{
25
    // default option mapping
26
    protected const OPTION_MAP = [
27
        'innerKey' => Relation::INNER_KEY,
28
    ];
29
30
    /** @var OptionMapper */
31
    private $optionMapper;
32
33
    /** @var RelationInterface[] */
34
    private $relations = [];
35
36
    /**
37
     * @param array $relations
38
     * @param array $optionMap
39
     */
40
    public function __construct(array $relations, array $optionMap = [])
41
    {
42
        $this->optionMapper = new OptionMapper($optionMap ?? self::OPTION_MAP);
43
44
        foreach ($relations as $id => $relation) {
45
            if (!$relation instanceof RelationInterface) {
46
                throw new \InvalidArgumentException(sprintf(
47
                    "Invalid relation type, RelationInterface excepted, `%s` given",
48
                    is_object($relation) ? get_class($relation) : gettype($relation)
49
                ));
50
            }
51
52
            $this->relations[$id] = $relation;
53
        }
54
    }
55
56
    /**
57
     * @param Registry $registry
58
     * @param Entity   $entity
59
     */
60
    public function compute(Registry $registry, Entity $entity)
61
    {
62
        foreach ($entity->getRelations() as $name => $r) {
63
            if (!isset($this->relations[$r->getType()])) {
64
                throw new BuilderException("Undefined relation type `{$r->getType()}`");
65
            }
66
67
            $schema = $this->relations[$r->getType()]->withContext(
68
                $entity->getRole(),
69
                $r->getTarget(),
70
                $this->optionMapper->map($r->getOptions())
71
            );
72
73
            $registry->registerRelation($entity, $name, $schema);
74
        }
75
    }
76
}