Passed
Pull Request — master (#29)
by Sébastien
12:35 queued 04:51
created

MorphTo   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 98.11%

Importance

Changes 0
Metric Value
wmc 15
eloc 43
dl 0
loc 146
ccs 52
cts 53
cp 0.9811
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A loadDistantFromType() 0 5 1
A link() 0 9 2
A relationQuery() 0 3 1
A loadDistantFrom() 0 5 1
A deleteAll() 0 7 1
A updateDistantInfos() 0 8 2
A join() 0 15 2
A joinRepositories() 0 6 1
A saveAll() 0 7 1
A load() 0 18 3
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 1
    public function link($owner): ReadCommandInterface
84
    {
85 1
        if (is_array($owner)) {
86
            throw new InvalidArgumentException('MorphTo relation do not supports querying on collection');
87
        }
88
89 1
        $this->loadDistantFrom($owner);
90
91 1
        return parent::link($owner);
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    #[WriteOperation]
98 4
    public function saveAll($owner, array $relations = []): int
99
    {
100 4
        $relations = $this->rearrangeWith($relations);
101 4
        $this->loadDistantFrom($owner);
102
103 4
        return parent::saveAll($owner, $relations[$this->discriminatorValue]);
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    #[WriteOperation]
110 4
    public function deleteAll($owner, array $relations = []): int
111
    {
112 4
        $relations = $this->rearrangeWith($relations);
113 4
        $this->loadDistantFrom($owner);
114
115 4
        return parent::deleteAll($owner, $relations[$this->discriminatorValue]);
116
    }
117
118
    /**
119
     * Change the current discriminator value 
120
     * and update the distant repository of this relation
121
     * 
122
     * @param mixed $type
123
     */
124 44
    protected function loadDistantFromType($type)
125
    {
126 44
        $this->discriminatorValue = $type;
127
128 44
        $this->updateDistantInfos();
129 44
    }
130
131
    /**
132
     * Change the current discriminator value from the entity
133
     * and update the distant repository of this relation
134
     * 
135
     * @param object $entity
136
     */
137 9
    protected function loadDistantFrom($entity)
138
    {
139 9
        $this->updateDiscriminatorValue($entity);
140
141 9
        $this->updateDistantInfos();
142 9
    }
143
144
    /**
145
     * Update the distant repository of this relation
146
     */
147 46
    protected function updateDistantInfos()
148
    {
149 46
        $infos = $this->map($this->discriminatorValue);
150
151 46
        $this->distant    = $this->local->repository($infos['entity']);
152 46
        $this->distantKey = $infos['distantKey'];
153
154 46
        $this->setConstraints(isset($infos['constraints']) ? $infos['constraints'] : []);
155 46
    }
156
157
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $constraints should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $keys should have a doc-comment as per coding-style.
Loading history...
158
     * {@inheritdoc}
159
     */
160 39
    protected function relationQuery($keys, $constraints): ReadCommandInterface
161
    {
162 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

162
        return $this->query($keys, $constraints)->/** @scrutinizer ignore-call */ by($this->distantKey);
Loading history...
163
    }
164
}
165