Passed
Push — master ( a1e60a...ad8bf2 )
by Anton
02:58
created

MorphedHasMany::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 4
dl 0
loc 4
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\ORM\Relation\Morphed;
11
12
use Cycle\ORM\Command\ContextCarrierInterface;
13
use Cycle\ORM\Exception\RelationException;
14
use Cycle\ORM\Heap\Node;
15
use Cycle\ORM\ORMInterface;
16
use Cycle\ORM\Promise\Collection\CollectionPromise;
17
use Cycle\ORM\Promise\PromiseMany;
18
use Cycle\ORM\Relation;
19
use Cycle\ORM\Relation\HasMany;
20
use Doctrine\Common\Collections\ArrayCollection;
21
22
class MorphedHasMany extends HasMany
23
{
24
    /** @var string */
25
    private $morphKey;
26
27
    /**
28
     * @param ORMInterface $orm
29
     * @param string       $target
30
     * @param string       $name
31
     * @param array        $schema
32
     */
33
    public function __construct(ORMInterface $orm, string $name, string $target, array $schema)
34
    {
35
        parent::__construct($orm, $name, $target, $schema);
36
        $this->morphKey = $schema[Relation::MORPH_KEY];
37
    }
38
39
    /**
40
     * @inheritdoc
41
     */
42
    public function initPromise(Node $parentNode): array
43
    {
44
        if (empty($innerKey = $this->fetchKey($parentNode, $this->innerKey))) {
45
            return [new ArrayCollection(), null];
46
        }
47
48
        $p = new PromiseMany(
49
            $this->orm,
50
            $this->target,
51
            [
52
                $this->outerKey => $innerKey,
53
                $this->morphKey => $parentNode->getRole(),
54
            ],
55
            $this->schema[Relation::WHERE] ?? []
56
        );
57
        $p->setConstrain($this->getConstrain());
58
59
        return [new CollectionPromise($p), $p];
60
    }
61
62
    /**
63
     * Persist related object.
64
     *
65
     * @param Node   $parentNode
66
     * @param object $related
67
     * @return ContextCarrierInterface
68
     */
69
    protected function queueStore(Node $parentNode, $related): ContextCarrierInterface
70
    {
71
        $relStore = parent::queueStore($parentNode, $related);
72
73
        $relNode = $this->getNode($related);
74
        if ($this->fetchKey($relNode, $this->morphKey) != $parentNode->getRole()) {
75
            $relStore->register($this->morphKey, $parentNode->getRole(), true);
76
            $relNode->register($this->morphKey, $parentNode->getRole(), true);
77
        }
78
79
        return $relStore;
80
    }
81
82
    /**
83
     * Assert that given entity is allowed for the relation.
84
     *
85
     * @param Node $relNode
86
     *
87
     * @throws RelationException
88
     */
89
    protected function assertValid(Node $relNode)
90
    {
91
        // no need to validate morphed relation yet
92
    }
93
}