Skip to content

Commit b52db34

Browse files
authored
Refactor populateInverseRelation() to separate ArrayAccess implementation (#354)
1 parent d8fa21d commit b52db34

1 file changed

Lines changed: 60 additions & 43 deletions

File tree

src/ActiveRelationTrait.php

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
use function array_keys;
2222
use function array_merge;
2323
use function array_unique;
24-
use function array_values;
2524
use function count;
2625
use function is_array;
2726
use function is_object;
@@ -276,9 +275,9 @@ public function populateRelation(string $name, array &$primaryModels): array
276275
$models = $this->all();
277276

278277
if (isset($viaModels, $viaQuery)) {
279-
$buckets = $this->buildBuckets($models, $this->link, $viaModels, $viaQuery);
278+
$buckets = $this->buildBuckets($models, $viaModels, $viaQuery);
280279
} else {
281-
$buckets = $this->buildBuckets($models, $this->link);
280+
$buckets = $this->buildBuckets($models);
282281
}
283282

284283
$this->indexBy($indexBy);
@@ -363,66 +362,84 @@ private function populateInverseRelation(
363362
$model = reset($models);
364363

365364
if ($model instanceof ActiveRecordInterface) {
366-
/** @var ActiveQuery $relation */
367-
$relation = $model->relationQuery($name);
368-
} else {
369-
/** @var ActiveQuery $relation */
370-
$relation = $this->getARInstance()->relationQuery($name);
365+
$this->populateInverseRelationToModels($models, $primaryModels, $name);
366+
return;
371367
}
372368

373-
if ($relation->getMultiple()) {
374-
$buckets = $this->buildBuckets($primaryModels, $relation->getLink(), null, null, false);
375-
if ($model instanceof ActiveRecordInterface) {
376-
foreach ($models as $model) {
377-
$key = $this->getModelKey($model, $relation->getLink());
378-
if ($model instanceof ActiveRecordInterface) {
379-
$model->populateRelation($name, $buckets[$key] ?? []);
369+
$primaryModel = reset($primaryModels);
370+
371+
if ($primaryModel instanceof ActiveRecordInterface) {
372+
if ($this->multiple) {
373+
foreach ($primaryModels as $primaryModel) {
374+
$models = $primaryModel->relation($primaryName);
375+
if (!empty($models)) {
376+
$this->populateInverseRelationToModels($models, $primaryModels, $name);
377+
$primaryModel->populateRelation($primaryName, $models);
380378
}
381379
}
382380
} else {
383-
foreach ($primaryModels as $i => $primaryModel) {
384-
if ($this->multiple) {
385-
foreach ($primaryModel as $j => $m) {
386-
$key = $this->getModelKey($m, $relation->getLink());
387-
$primaryModels[$i][$j][$name] = $buckets[$key] ?? [];
388-
}
389-
} elseif (!empty($primaryModel[$primaryName])) {
390-
$key = $this->getModelKey($primaryModel[$primaryName], $relation->getLink());
391-
$primaryModels[$i][$primaryName][$name] = $buckets[$key] ?? [];
381+
foreach ($primaryModels as $primaryModel) {
382+
$model = $primaryModel->relation($primaryName);
383+
if (!empty($model)) {
384+
$models = [$model];
385+
$this->populateInverseRelationToModels($models, $primaryModels, $name);
386+
$primaryModel->populateRelation($primaryName, $models[0]);
392387
}
393388
}
394389
}
395-
} elseif ($this->multiple) {
396-
foreach ($primaryModels as $i => $primaryModel) {
397-
foreach ($primaryModel[$primaryName] as $j => $m) {
398-
if ($m instanceof ActiveRecordInterface) {
399-
$m->populateRelation($name, $primaryModel);
400-
} else {
401-
$primaryModels[$i][$primaryName][$j][$name] = $primaryModel;
390+
} else {
391+
if ($this->multiple) {
392+
foreach ($primaryModels as &$primaryModel) {
393+
if (!empty($primaryModel[$primaryName])) {
394+
$this->populateInverseRelationToModels($primaryModel[$primaryName], $primaryModels, $name);
395+
}
396+
}
397+
} else {
398+
foreach ($primaryModels as &$primaryModel) {
399+
if (!empty($primaryModel[$primaryName])) {
400+
$models = [$primaryModel[$primaryName]];
401+
$this->populateInverseRelationToModels($models, $primaryModels, $name);
402+
$primaryModel[$primaryName] = $models[0];
402403
}
403404
}
404405
}
406+
}
407+
}
408+
409+
private function populateInverseRelationToModels(array &$models, array $primaryModels, string $name): void
410+
{
411+
$model = reset($models);
412+
$isArray = is_array($model);
413+
414+
/** @var ActiveQuery $relation */
415+
$relation = $isArray ? $this->getARInstance()->relationQuery($name) : $model->relationQuery($name);
416+
$buckets = $relation->buildBuckets($primaryModels);
417+
$link = $relation->getLink();
418+
$default = $relation->getMultiple() ? [] : null;
419+
420+
if ($isArray) {
421+
/** @var array $model */
422+
foreach ($models as &$model) {
423+
$key = $this->getModelKey($model, $link);
424+
$model[$name] = $buckets[$key] ?? $default;
425+
}
405426
} else {
406-
foreach ($primaryModels as $i => $primaryModel) {
407-
if ($primaryModel[$primaryName] instanceof ActiveRecordInterface) {
408-
$primaryModel[$primaryName]->populateRelation($name, $primaryModel);
409-
} elseif (!empty($primaryModel[$primaryName])) {
410-
$primaryModels[$i][$primaryName][$name] = $primaryModel;
411-
}
427+
/** @var ActiveRecordInterface $model */
428+
foreach ($models as $model) {
429+
$key = $this->getModelKey($model, $link);
430+
$model->populateRelation($name, $buckets[$key] ?? $default);
412431
}
413432
}
414433
}
415434

416435
private function buildBuckets(
417436
array $models,
418-
array $link,
419437
array $viaModels = null,
420-
self $viaQuery = null,
421-
bool $checkMultiple = true
438+
self $viaQuery = null
422439
): array {
423440
if ($viaModels !== null) {
424441
$map = [];
425-
$linkValues = array_values($link);
442+
$linkValues = $this->link;
426443
$viaLink = $viaQuery->link ?? [];
427444
$viaLinkKeys = array_keys($viaLink);
428445
$viaVia = null;
@@ -452,7 +469,7 @@ private function buildBuckets(
452469
}
453470

454471
$buckets = [];
455-
$linkKeys = array_keys($link);
472+
$linkKeys = array_keys($this->link);
456473

457474
if (isset($map)) {
458475
foreach ($models as $model) {
@@ -471,7 +488,7 @@ private function buildBuckets(
471488
}
472489
}
473490

474-
if ($checkMultiple && !$this->multiple) {
491+
if (!$this->multiple) {
475492
foreach ($buckets as $i => $bucket) {
476493
$buckets[$i] = reset($bucket);
477494
}

0 commit comments

Comments
 (0)