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
$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
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() 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
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() 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
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||||
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
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() 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
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||||
234 | { |
||||||||
235 | } |
||||||||
236 | |||||||||
237 | /** |
||||||||
238 | * {@inheritdoc} |
||||||||
239 | */ |
||||||||
240 | protected function applyWhereKeys(ReadCommandInterface $query, $value): ReadCommandInterface |
||||||||
241 | { |
||||||||
242 | return $query; |
||||||||
243 | } |
||||||||
244 | } |
||||||||
245 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.