1 | <?php |
||||||||
2 | |||||||||
3 | namespace Nip\Records\Relations; |
||||||||
4 | |||||||||
5 | use Nip\Database\Connections\Connection; |
||||||||
6 | use Nip\Database\Query\AbstractQuery; |
||||||||
7 | use Nip\Database\Query\Select as Query; |
||||||||
8 | use Nip\HelperBroker; |
||||||||
9 | use Exception; |
||||||||
10 | use Nip\Records\Collections\Collection; |
||||||||
11 | use Nip\Records\Collections\Collection as RecordCollection; |
||||||||
12 | use Nip\Records\Locator\Exceptions\InvalidModelException; |
||||||||
13 | use Nip\Records\Locator\ModelLocator; |
||||||||
14 | use Nip\Records\AbstractModels\Record; |
||||||||
15 | use Nip\Records\AbstractModels\RecordManager; |
||||||||
16 | use Nip\Records\Relations\Exceptions\RelationsNeedsAName; |
||||||||
17 | use Nip\Records\Relations\Traits\HasForeignKeyTrait; |
||||||||
18 | use Nip\Records\Relations\Traits\HasItemTrait; |
||||||||
19 | use Nip\Records\Relations\Traits\HasManagerTrait; |
||||||||
20 | use Nip\Records\Relations\Traits\HasPrimaryKeyTrait; |
||||||||
21 | use Nip\Records\Relations\Traits\HasWithTrait; |
||||||||
22 | use Nip_Helper_Arrays as ArraysHelper; |
||||||||
23 | |||||||||
24 | /** |
||||||||
25 | * Class Relation |
||||||||
26 | * @package Nip\Records\Relations |
||||||||
27 | */ |
||||||||
28 | abstract class Relation |
||||||||
29 | { |
||||||||
30 | use HasManagerTrait; |
||||||||
31 | use HasWithTrait; |
||||||||
32 | use HasForeignKeyTrait; |
||||||||
33 | use HasPrimaryKeyTrait; |
||||||||
34 | use HasItemTrait; |
||||||||
35 | |||||||||
36 | /** |
||||||||
37 | * @var |
||||||||
38 | */ |
||||||||
39 | protected $name = null; |
||||||||
40 | |||||||||
41 | /** |
||||||||
42 | * @var string |
||||||||
43 | */ |
||||||||
44 | protected $type = 'relation'; |
||||||||
45 | |||||||||
46 | /** |
||||||||
47 | * @var null|string |
||||||||
48 | */ |
||||||||
49 | protected $table = null; |
||||||||
50 | |||||||||
51 | /** |
||||||||
52 | * @var Query |
||||||||
53 | */ |
||||||||
54 | protected $query; |
||||||||
55 | |||||||||
56 | /** |
||||||||
57 | * @var bool |
||||||||
58 | */ |
||||||||
59 | protected $populated = false; |
||||||||
60 | |||||||||
61 | /** |
||||||||
62 | * @var array |
||||||||
63 | */ |
||||||||
64 | protected $params = []; |
||||||||
65 | |||||||||
66 | /** |
||||||||
67 | * @var null|Collection|Record |
||||||||
68 | */ |
||||||||
69 | protected $results = null; |
||||||||
70 | |||||||||
71 | /** |
||||||||
72 | * @return Query |
||||||||
73 | * @throws Exception |
||||||||
74 | */ |
||||||||
75 | 1 | public function getQuery() |
|||||||
76 | { |
||||||||
77 | 1 | if ($this->query == null) { |
|||||||
78 | 1 | $this->initQuery(); |
|||||||
79 | } |
||||||||
80 | |||||||||
81 | 1 | return $this->query; |
|||||||
82 | } |
||||||||
83 | |||||||||
84 | /** |
||||||||
85 | * @param $query |
||||||||
86 | * @return static |
||||||||
87 | */ |
||||||||
88 | public function setQuery($query) |
||||||||
89 | { |
||||||||
90 | $this->query = $query; |
||||||||
91 | |||||||||
92 | return $this; |
||||||||
93 | } |
||||||||
94 | |||||||||
95 | /** |
||||||||
96 | * @throws Exception |
||||||||
97 | */ |
||||||||
98 | 1 | public function initQuery() |
|||||||
99 | { |
||||||||
100 | 1 | $query = $this->newQuery(); |
|||||||
101 | 1 | $this->populateQuerySpecific($query); |
|||||||
102 | |||||||||
103 | 1 | $this->query = $query; |
|||||||
104 | 1 | } |
|||||||
105 | |||||||||
106 | /** |
||||||||
107 | * @return Query |
||||||||
108 | */ |
||||||||
109 | 3 | public function newQuery() |
|||||||
110 | { |
||||||||
111 | 3 | return $this->getWith()->paramsToQuery(); |
|||||||
112 | } |
||||||||
113 | |||||||||
114 | /** |
||||||||
115 | * @return mixed |
||||||||
116 | * @throws RelationsNeedsAName |
||||||||
117 | */ |
||||||||
118 | 4 | public function getName() |
|||||||
119 | { |
||||||||
120 | 4 | if ($this->name === null) { |
|||||||
121 | throw new RelationsNeedsAName(); |
||||||||
122 | } |
||||||||
123 | 4 | return $this->name; |
|||||||
124 | } |
||||||||
125 | |||||||||
126 | /** |
||||||||
127 | * @param string $name |
||||||||
128 | */ |
||||||||
129 | 11 | public function setName($name) |
|||||||
130 | { |
||||||||
131 | 11 | $this->name = $name; |
|||||||
132 | 11 | } |
|||||||
133 | |||||||||
134 | /** |
||||||||
135 | * @param $name |
||||||||
136 | * @return \Nip\Records\AbstractModels\RecordManager |
||||||||
137 | */ |
||||||||
138 | 4 | public function getModelManagerInstance($name) |
|||||||
139 | { |
||||||||
140 | 4 | return ModelLocator::get($name); |
|||||||
141 | } |
||||||||
142 | |||||||||
143 | |||||||||
144 | /** |
||||||||
145 | * @param AbstractQuery $query |
||||||||
146 | */ |
||||||||
147 | abstract public function populateQuerySpecific(AbstractQuery $query); |
||||||||
148 | |||||||||
149 | /** |
||||||||
150 | * @return \Nip\Database\Query\Delete |
||||||||
151 | * @throws Exception |
||||||||
152 | */ |
||||||||
153 | public function getDeleteQuery() |
||||||||
154 | { |
||||||||
155 | $query = $this->getWith()->newDeleteQuery(); |
||||||||
156 | $this->populateQuerySpecific($query); |
||||||||
157 | |||||||||
158 | return $query; |
||||||||
159 | } |
||||||||
160 | |||||||||
161 | /** |
||||||||
162 | * @return Connection |
||||||||
163 | */ |
||||||||
164 | 1 | public function getDB() |
|||||||
165 | { |
||||||||
166 | 1 | return $this->getManager()->getDB(); |
|||||||
167 | } |
||||||||
168 | |||||||||
169 | /** |
||||||||
170 | * @param $key |
||||||||
171 | * @return mixed |
||||||||
172 | */ |
||||||||
173 | 2 | public function getParam($key) |
|||||||
174 | { |
||||||||
175 | 2 | return $this->hasParam($key) ? $this->params[$key] : null; |
|||||||
176 | } |
||||||||
177 | |||||||||
178 | /** |
||||||||
179 | * @param $key |
||||||||
180 | * @return boolean |
||||||||
181 | */ |
||||||||
182 | 2 | public function hasParam($key) |
|||||||
183 | { |
||||||||
184 | 2 | return isset($this->params[$key]); |
|||||||
185 | } |
||||||||
186 | |||||||||
187 | /** |
||||||||
188 | * @param $params |
||||||||
189 | */ |
||||||||
190 | 6 | public function addParams($params) |
|||||||
191 | { |
||||||||
192 | 6 | $this->checkParamClass($params); |
|||||||
193 | 6 | $this->checkParamWith($params); |
|||||||
194 | 6 | $this->checkParamWithPK($params); |
|||||||
195 | 6 | $this->checkParamTable($params); |
|||||||
196 | 6 | $this->checkParamFk($params); |
|||||||
197 | 6 | $this->checkParamPrimaryKey($params); |
|||||||
198 | 6 | $this->setParams($params); |
|||||||
199 | 6 | } |
|||||||
200 | |||||||||
201 | /** |
||||||||
202 | * @param $params |
||||||||
203 | */ |
||||||||
204 | 6 | public function checkParamClass($params) |
|||||||
205 | { |
||||||||
206 | 6 | if (isset($params['class'])) { |
|||||||
207 | /** @noinspection PhpUnhandledExceptionInspection */ |
||||||||
208 | $this->setWithClass($params['class']); |
||||||||
209 | unset($params['class']); |
||||||||
210 | } |
||||||||
211 | 6 | } |
|||||||
212 | |||||||||
213 | /** |
||||||||
214 | * @param $params |
||||||||
215 | */ |
||||||||
216 | 6 | public function checkParamTable($params) |
|||||||
217 | { |
||||||||
218 | 6 | if (isset($params['table'])) { |
|||||||
219 | $this->setTable($params['table']); |
||||||||
220 | unset($params['table']); |
||||||||
221 | } |
||||||||
222 | 6 | } |
|||||||
223 | |||||||||
224 | /** |
||||||||
225 | * @return array |
||||||||
226 | */ |
||||||||
227 | 1 | public function getParams(): array |
|||||||
228 | { |
||||||||
229 | 1 | return $this->params; |
|||||||
230 | } |
||||||||
231 | |||||||||
232 | /** |
||||||||
233 | * @param $params |
||||||||
234 | */ |
||||||||
235 | 6 | public function setParams($params) |
|||||||
236 | { |
||||||||
237 | 6 | $this->params = $params; |
|||||||
238 | 6 | } |
|||||||
239 | |||||||||
240 | /** |
||||||||
241 | * @return string |
||||||||
242 | */ |
||||||||
243 | 2 | public function getTable() |
|||||||
244 | { |
||||||||
245 | 2 | if ($this->table == null) { |
|||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||||
246 | 2 | $this->initTable(); |
|||||||
247 | } |
||||||||
248 | |||||||||
249 | 2 | return $this->table; |
|||||||
250 | } |
||||||||
251 | |||||||||
252 | /** |
||||||||
253 | * @param $name |
||||||||
254 | */ |
||||||||
255 | 2 | public function setTable($name) |
|||||||
256 | { |
||||||||
257 | 2 | $this->table = $name; |
|||||||
258 | 2 | } |
|||||||
259 | |||||||||
260 | 2 | protected function initTable() |
|||||||
261 | { |
||||||||
262 | 2 | $this->setTable($this->generateTable()); |
|||||||
263 | 2 | } |
|||||||
264 | |||||||||
265 | /** |
||||||||
266 | * @return string |
||||||||
267 | */ |
||||||||
268 | protected function generateTable() |
||||||||
269 | { |
||||||||
270 | return $this->getWith()->getTable(); |
||||||||
271 | } |
||||||||
272 | |||||||||
273 | /** |
||||||||
274 | * Get the results of the relationship. |
||||||||
275 | * @return Record|RecordCollection |
||||||||
276 | */ |
||||||||
277 | 4 | public function getResults() |
|||||||
278 | { |
||||||||
279 | 4 | if (!$this->isPopulated()) { |
|||||||
280 | 4 | $this->initResults(); |
|||||||
281 | } |
||||||||
282 | |||||||||
283 | 4 | return $this->results; |
|||||||
284 | } |
||||||||
285 | |||||||||
286 | /** |
||||||||
287 | * @param $results |
||||||||
288 | * @return null |
||||||||
289 | */ |
||||||||
290 | 4 | public function setResults($results) |
|||||||
291 | { |
||||||||
292 | 4 | $this->results = $results; |
|||||||
293 | 4 | $this->populated = true; |
|||||||
294 | |||||||||
295 | 4 | return $this->results; |
|||||||
296 | } |
||||||||
297 | |||||||||
298 | /** |
||||||||
299 | * @return bool |
||||||||
300 | */ |
||||||||
301 | 1 | public function isPopulatable() |
|||||||
302 | { |
||||||||
303 | 1 | return !empty($this->getItemRelationPrimaryKey()); |
|||||||
304 | } |
||||||||
305 | |||||||||
306 | /** |
||||||||
307 | * @return bool |
||||||||
308 | */ |
||||||||
309 | 4 | public function isPopulated() |
|||||||
310 | { |
||||||||
311 | 4 | return $this->populated == true; |
|||||||
0 ignored issues
–
show
|
|||||||||
312 | } |
||||||||
313 | |||||||||
314 | abstract public function initResults(); |
||||||||
315 | |||||||||
316 | /** |
||||||||
317 | * @param RecordCollection $collection |
||||||||
318 | * @return RecordCollection |
||||||||
319 | * @throws Exception |
||||||||
320 | */ |
||||||||
321 | public function getEagerResults($collection) |
||||||||
322 | { |
||||||||
323 | if ($collection->count() < 1) { |
||||||||
324 | return $this->getWith()->newCollection(); |
||||||||
325 | } |
||||||||
326 | $query = $this->getEagerQuery($collection); |
||||||||
327 | |||||||||
328 | return $this->getWith()->findByQuery($query); |
||||||||
329 | } |
||||||||
330 | |||||||||
331 | /** |
||||||||
332 | * @param RecordCollection $collection |
||||||||
333 | * @return Query |
||||||||
334 | */ |
||||||||
335 | 2 | public function getEagerQuery(RecordCollection $collection) |
|||||||
336 | { |
||||||||
337 | 2 | $fkList = $this->getEagerFkList($collection); |
|||||||
338 | 2 | $query = $this->populateEagerQueryFromFkList($this->newQuery(), $fkList); |
|||||||
339 | 2 | return $query; |
|||||||
340 | } |
||||||||
341 | |||||||||
342 | /** |
||||||||
343 | * @param Query $query |
||||||||
344 | * @param array $fkList |
||||||||
345 | * @return Query |
||||||||
346 | */ |
||||||||
347 | 1 | protected function populateEagerQueryFromFkList($query, $fkList) |
|||||||
348 | { |
||||||||
349 | 1 | $query->where($this->getWithPK() . ' IN ?', $fkList); |
|||||||
350 | |||||||||
351 | 1 | return $query; |
|||||||
352 | } |
||||||||
353 | |||||||||
354 | /** |
||||||||
355 | * @param RecordCollection $collection |
||||||||
356 | * @return array |
||||||||
357 | */ |
||||||||
358 | 2 | public function getEagerFkList(RecordCollection $collection) |
|||||||
359 | { |
||||||||
360 | /** @var ArraysHelper $arrayHelper */ |
||||||||
361 | 2 | $arrayHelper = HelperBroker::get('Arrays'); |
|||||||
362 | 2 | $return = $arrayHelper->pluck($collection, $this->getFK()); |
|||||||
363 | |||||||||
364 | 2 | return array_unique($return); |
|||||||
365 | } |
||||||||
366 | |||||||||
367 | /** |
||||||||
368 | * @param RecordCollection $collection |
||||||||
369 | * @param RecordCollection $recordsLoaded |
||||||||
370 | * |
||||||||
371 | * @return RecordCollection |
||||||||
372 | */ |
||||||||
373 | public function match(RecordCollection $collection, RecordCollection $recordsLoaded) |
||||||||
374 | { |
||||||||
375 | $dictionary = $this->buildDictionary($recordsLoaded); |
||||||||
376 | |||||||||
377 | foreach ($collection as $record) { |
||||||||
378 | /** @var Record $record */ |
||||||||
379 | $results = $this->getResultsFromCollectionDictionary($dictionary, $collection, $record); |
||||||||
380 | /** @noinspection PhpUnhandledExceptionInspection */ |
||||||||
381 | $record->getRelation($this->getName())->setResults($results); |
||||||||
0 ignored issues
–
show
The method
getRelation() does not exist on Nip\Records\AbstractModels\Record . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() The method
setResults() does not exist on Nip\Helpers\AbstractHelper . It seems like you code against a sub-type of Nip\Helpers\AbstractHelper such as Nip_Helper_Url or Nip\Helpers\View\Stylesheets or Nip\Helpers\View\Strings or Nip\Helpers\View\Paginator or Nip\Helpers\View\Arrays or Nip\Helpers\View\Icontext or Nip\Helpers\View\Color or Nip\Helpers\View\Scripts or Nip\Helpers\View\Url .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||||
382 | } |
||||||||
383 | |||||||||
384 | return $recordsLoaded; |
||||||||
385 | } |
||||||||
386 | |||||||||
387 | /** |
||||||||
388 | * Build model dictionary keyed by the relation's foreign key. |
||||||||
389 | * |
||||||||
390 | * @param RecordCollection $collection |
||||||||
391 | * @return array |
||||||||
392 | */ |
||||||||
393 | abstract protected function buildDictionary(RecordCollection $collection); |
||||||||
394 | |||||||||
395 | /** |
||||||||
396 | * @param $dictionary |
||||||||
397 | * @param Collection $collection |
||||||||
398 | * @param Record $record |
||||||||
399 | * @return mixed |
||||||||
400 | */ |
||||||||
401 | abstract public function getResultsFromCollectionDictionary($dictionary, $collection, $record); |
||||||||
402 | |||||||||
403 | public function save() |
||||||||
404 | { |
||||||||
405 | } |
||||||||
406 | |||||||||
407 | /** |
||||||||
408 | * @return string |
||||||||
409 | */ |
||||||||
410 | public function getType() |
||||||||
411 | { |
||||||||
412 | return $this->type; |
||||||||
413 | } |
||||||||
414 | |||||||||
415 | /** @noinspection PhpDocMissingThrowsInspection |
||||||||
416 | * @return string |
||||||||
417 | */ |
||||||||
418 | 1 | protected function debugString() |
|||||||
419 | { |
||||||||
420 | return 'Relation' |
||||||||
421 | 1 | . ' Manager:[' . ($this->hasManager() ? $this->getManager()->getClassName() : '') . ']' |
|||||||
422 | 1 | . ' name:[' . $this->getName() . '] ' |
|||||||
423 | 1 | . ' params:[' . serialize($this->getParams()) . ']'; |
|||||||
424 | } |
||||||||
425 | } |
||||||||
426 |