Skip to content

Commit

Permalink
Refactor populateInverseRelation() to separate ArrayAccess implem…
Browse files Browse the repository at this point in the history
…entation
  • Loading branch information
Tigrov committed May 27, 2024
1 parent d8fa21d commit fd76c5b
Showing 1 changed file with 89 additions and 31 deletions.
120 changes: 89 additions & 31 deletions src/ActiveRelationTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,60 +365,118 @@ private function populateInverseRelation(
if ($model instanceof ActiveRecordInterface) {
/** @var ActiveQuery $relation */
$relation = $model->relationQuery($name);
} else {
/** @var ActiveQuery $relation */
$relation = $this->getARInstance()->relationQuery($name);
$buckets = $relation->buildBuckets($primaryModels, $relation->getLink());
$this->populateRelationFromBuckets($models, $name, $relation->getLink(), $buckets);

return;
}

/** @var ActiveQuery $relation */
$relation = $this->getARInstance()->relationQuery($name);

$link = $relation->getLink();
$primaryModel = reset($primaryModels);

if ($relation->getMultiple()) {
$buckets = $this->buildBuckets($primaryModels, $relation->getLink(), null, null, false);
if ($model instanceof ActiveRecordInterface) {
foreach ($models as $model) {
$key = $this->getModelKey($model, $relation->getLink());
if ($model instanceof ActiveRecordInterface) {
$model->populateRelation($name, $buckets[$key] ?? []);
$buckets = $relation->buildBuckets($primaryModels, $link);

if ($primaryModel instanceof ActiveRecordInterface) {
if ($this->multiple) {
foreach ($primaryModels as $primaryModel) {
$models = $primaryModel->relation($primaryName);
$this->populateRelationFromBuckets($models, $name, $link, $buckets);
}
} else {
foreach ($primaryModels as $primaryModel) {
$models = [$primaryModel->relation($primaryName)];
$this->populateRelationFromBuckets($models, $name, $link, $buckets);
}
}
} else {
foreach ($primaryModels as $i => $primaryModel) {
if ($this->multiple) {
foreach ($primaryModel as $j => $m) {
$key = $this->getModelKey($m, $relation->getLink());
$primaryModels[$i][$j][$name] = $buckets[$key] ?? [];
}
} elseif (!empty($primaryModel[$primaryName])) {
$key = $this->getModelKey($primaryModel[$primaryName], $relation->getLink());
$primaryModels[$i][$primaryName][$name] = $buckets[$key] ?? [];
if ($this->multiple) {
foreach ($primaryModels as &$primaryModel) {
$primaryModel[$primaryName] =
$this->populateRelationFromBuckets($primaryModel[$primaryName], $name, $link, $buckets);
}
} else {
foreach ($primaryModels as &$primaryModel) {
$primaryModel[$primaryName] =
$this->populateRelationFromBuckets([$primaryModel[$primaryName]], $name, $link, $buckets)[0];
}
}
}
} elseif ($this->multiple) {
foreach ($primaryModels as $i => $primaryModel) {
foreach ($primaryModel[$primaryName] as $j => $m) {
if ($m instanceof ActiveRecordInterface) {
$m->populateRelation($name, $primaryModel);
if ($primaryModel instanceof ActiveRecordInterface) {
foreach ($primaryModels as $primaryModel) {
$models = $primaryModel->relation($primaryName);

$model = reset($models);
if ($model instanceof ActiveRecordInterface) {
foreach ($models as $model) {
$model->populateRelation($name, $primaryModel);
}
} else {
$primaryModels[$i][$primaryName][$j][$name] = $primaryModel;
foreach ($models as &$model) {
$model[$name] = $primaryModel;
}
unset($model);

$primaryModel->populateRelation($primaryName, $models);
}
}
} else {
foreach ($primaryModels as $i => $primaryModel) {
foreach ($primaryModel[$primaryName] as $j => $model) {
if ($model instanceof ActiveRecordInterface) {
$model->populateRelation($name, $primaryModel);
} else {
$primaryModels[$i][$primaryName][$j][$name] = $primaryModel;
}
}
}
}
} else {
foreach ($primaryModels as $i => $primaryModel) {
if ($primaryModel[$primaryName] instanceof ActiveRecordInterface) {
$primaryModel[$primaryName]->populateRelation($name, $primaryModel);
} elseif (!empty($primaryModel[$primaryName])) {
$primaryModels[$i][$primaryName][$name] = $primaryModel;
if ($primaryModel instanceof ActiveRecordInterface) {
foreach ($primaryModels as $primaryModel) {
$model = $primaryModel->relation($primaryName);
if ($model instanceof ActiveRecordInterface) {
$model->populateRelation($name, $primaryModel);
}
}
} else {
foreach ($primaryModels as $i => $primaryModel) {
if (!empty($primaryModel[$primaryName])) {
$primaryModels[$i][$primaryName][$name] = $primaryModel;
}
}
}
}
}

private function populateRelationFromBuckets(array $models, string $name, array $link, array $buckets): array
{
$model = reset($models);
if ($model instanceof ActiveRecordInterface) {
/** @var ActiveRecordInterface $model */
foreach ($models as $model) {
$key = $this->getModelKey($model, $link);
$model->populateRelation($name, $buckets[$key] ?? []);
}
} else {
foreach ($models as $i => $model) {
$key = $this->getModelKey($model, $link);
$models[$i][$name] = $buckets[$key] ?? [];
}
}

return $models;
}

private function buildBuckets(
array $models,
array $link,
array $viaModels = null,
self $viaQuery = null,
bool $checkMultiple = true
self $viaQuery = null
): array {
if ($viaModels !== null) {
$map = [];
Expand Down Expand Up @@ -471,7 +529,7 @@ private function buildBuckets(
}
}

if ($checkMultiple && !$this->multiple) {
if (!$this->multiple) {
foreach ($buckets as $i => $bucket) {
$buckets[$i] = reset($bucket);
}
Expand Down

0 comments on commit fd76c5b

Please sign in to comment.