Issues (590)

src/Relations/ByInheritance.php (6 issues)

Severity
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\Mapper\SingleTableInheritanceMapper;
8
use Bdf\Prime\Query\Contract\EntityJoinable;
9
use Bdf\Prime\Query\QueryInterface;
10
use Bdf\Prime\Query\Contract\ReadOperation;
11
use Bdf\Prime\Query\Contract\WriteOperation;
12
use Bdf\Prime\Query\ReadCommandInterface;
13
use Bdf\Prime\Relations\Util\ForeignKeyRelation;
14
use Bdf\Prime\Repository\RepositoryInterface;
15
use LogicException;
16
17
/**
18
 * ByInheritance
19
 *
20
 * @todo options ?
21
 *
22
 * @template L as object
23
 *
24
 * @extends AbstractRelation<L, object>
25
 */
26
class ByInheritance extends AbstractRelation
27
{
28
    /** @use Polymorph<L> */
29
    use Polymorph;
30
    /** @use ForeignKeyRelation<L, object> */
31
    use ForeignKeyRelation;
32
33
    /**
34
     * Set inheritance relation
35
     *
36
     * @param string $attributeAim
37
     * @param RepositoryInterface<L> $local
38
     * @param string $localKey
39
     */
40 34
    public function __construct(string $attributeAim, RepositoryInterface $local, string $localKey)
41
    {
42 34
        parent::__construct($attributeAim, $local);
43
44 34
        $this->localKey = $localKey;
45
46 34
        $mapper = $local->mapper();
47
48 34
        if (!$mapper instanceof SingleTableInheritanceMapper) {
49 3
            throw new LogicException('The mapper could not manage single table inheritance relation');
50
        }
51
52 31
        $this->setDiscriminator($mapper->getDiscriminatorColumn());
53 31
        $this->setMap($mapper->getEntityMap());
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59 12
    public function relationRepository(): RepositoryInterface
60
    {
61 12
        return $this->subRelation()->relationRepository();
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    #[ReadOperation]
68 45
    public function load(EntityIndexerInterface $collection, array $with = [], $constraints = [], array $without = []): void
69
    {
70 45
        if ($collection->empty()) {
71 3
            return;
72
        }
73
74 45
        $with = $this->rearrangeWith($with);
75 45
        $without = $this->rearrangeWithout($without);
76
77 45
        foreach ($collection->by($this->discriminator) as $type => $chunk) {
78 45
            $this->discriminatorValue = $type;
79 45
            $subRelation = $this->subRelation();
80
81 45
            $subRelation->load(
82 45
                EntityIndexer::fromArray($subRelation->localRepository()->mapper(), $chunk),
83 45
                $with[$type],
84 45
                $constraints,
85 45
                $without[$type]
86 45
            );
87
        }
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function link($owner): ReadCommandInterface
94
    {
95
        $this->updateDiscriminatorValue($owner);
96
97
        return $this->subRelation()->link($owner);
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103 12
    public function join(EntityJoinable $query, string $alias): void
104
    {
105 12
        $parts = explode('#', $alias);
106
107 12
        if (!isset($parts[1])) {
108
            throw new LogicException('Joins are not supported on polymorph without discriminator');
109
        }
110
111 12
        $this->discriminatorValue = end($parts);
112
113
        //Use real alias
114 12
        $this->subRelation()->setLocalAlias($this->localAlias)->join($query, $parts[0]);
115
116
        //TODO should be in join clause
117 12
        $query->where($this->getLocalAlias($query).$this->discriminator, $this->discriminatorValue);
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 12
    public function joinRepositories(EntityJoinable $query, string $alias, $discriminator = null): array
124
    {
125 12
        $this->discriminatorValue = $discriminator;
126
127 12
        return [
128 12
            $alias => $this->relationRepository()
129 12
        ];
130
    }
131
132
    /**
133
     * {@inheritdoc}
134
     */
135
    public function associate($owner, $entity)
136
    {
137
        $this->updateDiscriminatorValue($owner);
138
139
        return $this->subRelation()->associate($owner, $entity);
140
    }
141
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function dissociate($owner)
146
    {
147
        $this->updateDiscriminatorValue($owner);
148
149
        return $this->subRelation()->dissociate($owner);
150
    }
151
152
    /**
153
     * {@inheritdoc}
154
     */
155
    public function create($owner, array $data = [])
156
    {
157
        $this->updateDiscriminatorValue($owner);
158
159
        return $this->subRelation()->create($owner, $data);
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165
    #[WriteOperation]
166
    public function add($owner, $related): int
167
    {
168
        $this->updateDiscriminatorValue($owner);
169
170
        return $this->subRelation()->add($owner, $related);
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176
    #[WriteOperation]
177 3
    public function saveAll($owner, array $relations = []): int
178
    {
179 3
        $relations = $this->rearrangeWith($relations);
180 3
        $this->updateDiscriminatorValue($owner);
181
182 3
        return $this->subRelation()->saveAll($owner, $relations[$this->discriminatorValue]);
183
    }
184
185
    /**
186
     * {@inheritdoc}
187
     */
188
    #[WriteOperation]
189 3
    public function deleteAll($owner, array $relations = []): int
190
    {
191 3
        $relations = $this->rearrangeWith($relations);
192 3
        $this->updateDiscriminatorValue($owner);
193
194 3
        return $this->subRelation()->deleteAll($owner, $relations[$this->discriminatorValue]);
195
    }
196
197
    /**
198
     * Get the delagated sub relation
199
     *
200
     * @return RelationInterface<L, object>
201
     */
202 45
    protected function subRelation(): RelationInterface
203
    {
204
        /** @var array{entity:class-string<L>} $infos */
205 45
        $infos = $this->map($this->discriminatorValue);
206
207 45
        $relation = $this->local->repository($infos['entity'])
208 45
            ->relation($this->attributeAim);
209
210
        // TODO doit on redescendre les options sur la relation ?
211
212 45
        return $relation;
213
    }
214
215
    /**
216
     * Unused method by inheritance
217
     *
218
     * {@inheritdoc}
219
     *
220
     * @return void
221
     */
222
    protected function relations($keys, $with, $constraints, $without): void
0 ignored issues
show
The parameter $without is not used and could be removed. ( Ignorable by Annotation )

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

222
    protected function relations($keys, $with, $constraints, /** @scrutinizer ignore-unused */ $without): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $constraints is not used and could be removed. ( Ignorable by Annotation )

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

222
    protected function relations($keys, $with, /** @scrutinizer ignore-unused */ $constraints, $without): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $with is not used and could be removed. ( Ignorable by Annotation )

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

222
    protected function relations($keys, /** @scrutinizer ignore-unused */ $with, $constraints, $without): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $keys is not used and could be removed. ( Ignorable by Annotation )

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

222
    protected function relations(/** @scrutinizer ignore-unused */ $keys, $with, $constraints, $without): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
223
    {
224
    }
225
226
    /**
227
     * Unused method by inheritance
228
     *
229
     * {@inheritdoc}
230
     *
231
     * @return void
232
     */
233
    protected function match($collection, $relations): void
0 ignored issues
show
The parameter $collection is not used and could be removed. ( Ignorable by Annotation )

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

233
    protected function match(/** @scrutinizer ignore-unused */ $collection, $relations): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $relations is not used and could be removed. ( Ignorable by Annotation )

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

233
    protected function match($collection, /** @scrutinizer ignore-unused */ $relations): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
234
    {
235
    }
236
237
    /**
238
     * {@inheritdoc}
239
     */
240
    protected function applyWhereKeys(ReadCommandInterface $query, $value): ReadCommandInterface
241
    {
242
        return $query;
243
    }
244
}
245