Passed
Pull Request — master (#29)
by Sébastien
08:57
created

MorphTo::relationQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Bdf\Prime\Relations;
4
5
use Bdf\Prime\Collection\Indexer\EntityIndexer;
6
use Bdf\Prime\Collection\Indexer\EntityIndexerInterface;
7
use Bdf\Prime\Query\Contract\EntityJoinable;
8
use Bdf\Prime\Query\Contract\ReadOperation;
9
use Bdf\Prime\Query\Contract\WriteOperation;
10
use Bdf\Prime\Query\ReadCommandInterface;
11
use InvalidArgumentException;
12
use LogicException;
13
14
/**
15
 * MorphTo
16
 */
17
class MorphTo extends BelongsTo
18
{
19
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $query should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $alias should have a doc-comment as per coding-style.
Loading history...
20
     * {@inheritdoc}
21
     *
22
     * The alias should have #[sub entity] at its end
0 ignored issues
show
introduced by
Doc comment long description must end with a full stop
Loading history...
23
     */
0 ignored issues
show
Coding Style Documentation introduced by
Missing @throws tag in function comment
Loading history...
24 6
    public function join(EntityJoinable $query, string $alias): void
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line before function; 0 found
Loading history...
25
    {
26 6
        $parts = explode('#', $alias);
27
28 6
        if (!isset($parts[1])) {
29 1
            throw new LogicException('Joins are not supported on polymorph without discriminator');
30
        }
31
32 5
        $this->loadDistantFromType(end($parts));
33
34
        //TODO should be in join clause
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
Coding Style introduced by
No space found before comment text; expected "// TODO should be in join clause" but found "//TODO should be in join clause"
Loading history...
35 5
        $query->where($this->getLocalAlias($query).$this->discriminator, $this->discriminatorValue);
36
37
        // Join to the real alias (i.e. without the discriminator)
38 5
        parent::join($query, $parts[0]);
39 5
    }
40
41
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $alias should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $query should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $discriminator should have a doc-comment as per coding-style.
Loading history...
42
     * {@inheritdoc}
43
     */
44 5
    public function joinRepositories(EntityJoinable $query, string $alias, $discriminator = null): array
0 ignored issues
show
Coding Style introduced by
The method parameter $query is never used
Loading history...
45
    {
46 5
        $this->loadDistantFromType($discriminator);
47
48
        return [
49 5
            $alias => $this->relationRepository()
0 ignored issues
show
introduced by
A comma should follow the last multiline array item. Found: )
Loading history...
50
        ];
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    #[ReadOperation]
57 44
    public function load(EntityIndexerInterface $collection, array $with = [], $constraints = [], array $without = []): void
58
    {
59 44
        if ($collection->empty()) {
60 9
            return;
61
        }
62
63 39
        $with = $this->rearrangeWith($with);
64 39
        $without = $this->rearrangeWithout($without);
65
66 39
        foreach ($collection->by($this->discriminator) as $type => $chunk) {
67 39
            $this->loadDistantFromType($type);
68
69 39
            parent::load(
70 39
                EntityIndexer::fromArray($this->local->mapper(), $chunk),
71 39
                $with[$type],
72 39
                $constraints,
73 39
                $without[$type]
74
            );
75
        }
76 38
    }
77
78
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $owner should have a doc-comment as per coding-style.
Loading history...
79
     * {@inheritdoc}
80
     *
81
     * @fixme Do not works with EntityCollection
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task
Loading history...
82
     */
0 ignored issues
show
Coding Style Documentation introduced by
Missing @throws tag in function comment
Loading history...
83 2
    public function link($owner): ReadCommandInterface
84
    {
85 2
        if (is_array($owner)) {
86
            throw new InvalidArgumentException('MorphTo relation do not supports querying on collection');
87
        }
88
89 2
        $this->loadDistantFrom($owner);
90
91 2
        return parent::link($owner);
92
    }
93
94
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $entity should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $owner should have a doc-comment as per coding-style.
Loading history...
95
     * {@inheritdoc}
96
     */
97 2
    public function associate($owner, $entity)
98
    {
99 2
        $this->loadDistantFromType($this->discriminator(get_class($entity)));
100
101 2
        return parent::associate($owner, $entity);
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    #[WriteOperation]
108 4
    public function saveAll($owner, array $relations = []): int
109
    {
110 4
        $relations = $this->rearrangeWith($relations);
111 4
        $this->loadDistantFrom($owner);
112
113 4
        return parent::saveAll($owner, $relations[$this->discriminatorValue]);
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    #[WriteOperation]
120 4
    public function deleteAll($owner, array $relations = []): int
121
    {
122 4
        $relations = $this->rearrangeWith($relations);
123 4
        $this->loadDistantFrom($owner);
124
125 4
        return parent::deleteAll($owner, $relations[$this->discriminatorValue]);
126
    }
127
128
    /**
129
     * Change the current discriminator value 
130
     * and update the distant repository of this relation
131
     * 
132
     * @param mixed $type
133
     */
134 46
    protected function loadDistantFromType($type)
135
    {
136 46
        $this->discriminatorValue = $type;
137
138 46
        $this->updateDistantInfos();
139 46
    }
140
141
    /**
142
     * Change the current discriminator value from the entity
143
     * and update the distant repository of this relation
144
     * 
145
     * @param object $entity
146
     */
147 10
    protected function loadDistantFrom($entity)
148
    {
149 10
        $this->updateDiscriminatorValue($entity);
150
151 10
        $this->updateDistantInfos();
152 10
    }
153
154
    /**
155
     * Update the distant repository of this relation
156
     */
157 48
    protected function updateDistantInfos()
158
    {
159 48
        $infos = $this->map($this->discriminatorValue);
160
161 48
        $this->distant    = $this->local->repository($infos['entity']);
162 48
        $this->distantKey = $infos['distantKey'];
163
164 48
        $this->setConstraints(isset($infos['constraints']) ? $infos['constraints'] : []);
165 48
    }
166
167
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $keys should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $constraints should have a doc-comment as per coding-style.
Loading history...
168
     * {@inheritdoc}
169
     */
170 39
    protected function relationQuery($keys, $constraints): ReadCommandInterface
171
    {
172 39
        return $this->query($keys, $constraints)->by($this->distantKey);
0 ignored issues
show
Bug introduced by
The method by() does not exist on Bdf\Prime\Query\QueryInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Bdf\Prime\Query\SqlQueryInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

172
        return $this->query($keys, $constraints)->/** @scrutinizer ignore-call */ by($this->distantKey);
Loading history...
173
    }
174
}
175