Skip to content

Commit

Permalink
Refactor filterByModels() to separate ArrayAccess implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Tigrov committed May 27, 2024
1 parent fe61e2d commit d67403c
Showing 1 changed file with 58 additions and 38 deletions.
96 changes: 58 additions & 38 deletions src/ActiveRelationTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
use Yiisoft\Db\Exception\InvalidArgumentException;
use Yiisoft\Db\Exception\InvalidConfigException;
use Yiisoft\Db\Exception\NotSupportedException;
use Yiisoft\Db\Expression\ArrayExpression;

use function array_combine;
use function array_diff_key;
use function array_fill_keys;
use function array_filter;
use function array_intersect_key;
use function array_keys;
use function array_merge;
use function array_unique;
Expand Down Expand Up @@ -541,64 +544,81 @@ private function prefixKeyColumns(array $attributes): array
*/
protected function filterByModels(array $models): void
{
$attributes = array_keys($this->link);
if (empty($this->link)) {
$this->emulateExecution();
$this->andWhere('1=0');
return;

Check warning on line 550 in src/ActiveRelationTrait.php

View check run for this annotation

Codecov / codecov/patch

src/ActiveRelationTrait.php#L548-L550

Added lines #L548 - L550 were not covered by tests
}

$attributes = array_keys($this->link);
$attributes = $this->prefixKeyColumns($attributes);

$model = reset($models);
$values = [];

if (count($attributes) === 1) {
/** single key */
$attribute = reset($this->link);
foreach ($models as $model) {
$value = isset($model[$attribute]) || (is_object($model) && property_exists($model, $attribute)) ? $model[$attribute] : null;
if ($value !== null) {
if (is_array($value)) {
$values = array_merge($values, $value);
} elseif ($value instanceof ArrayExpression && $value->getDimension() === 1) {
$values = array_merge($values, $value->getValue());
} else {
$values[] = $value;

if ($model instanceof ActiveRecordInterface) {
foreach ($models as $model) {
$value = $model->getAttribute($attribute);

if ($value !== null) {
if (is_array($value)) {
$values[] = $value;

Check warning on line 569 in src/ActiveRelationTrait.php

View check run for this annotation

Codecov / codecov/patch

src/ActiveRelationTrait.php#L569

Added line #L569 was not covered by tests
} else {
$values[] = [$value];
}
}
}
} else {
foreach ($models as $model) {
if (isset($model[$attribute])) {
if (is_array($model[$attribute])) {
$values[] = $model[$attribute];

Check warning on line 579 in src/ActiveRelationTrait.php

View check run for this annotation

Codecov / codecov/patch

src/ActiveRelationTrait.php#L579

Added line #L579 was not covered by tests
} else {
$values[] = [$model[$attribute]];
}
}
}
}

if (empty($values)) {
$this->emulateExecution();
if (!empty($values)) {
$values = array_merge(...$values);

$scalarValues = array_filter($values, 'is_scalar');
$nonScalarValues = array_diff_key($values, $scalarValues);

$scalarValues = array_unique($scalarValues);
$values = [...$scalarValues, ...$nonScalarValues];
}
} else {
/**
* composite keys ensure keys of $this->link are prefixed the same way as $attributes.
*/
$prefixedLink = array_combine($attributes, $this->link);
$nulls = array_fill_keys($this->link, null);

foreach ($models as $model) {
$v = [];
if ($model instanceof ActiveRecordInterface) {
foreach ($models as $model) {
$value = $model->getAttributes($this->link);

foreach ($prefixedLink as $attribute => $link) {
$v[$attribute] = $model[$link];
if (!empty($value)) {
$values[] = array_combine($attributes, array_merge($nulls, $value));
}
}
} else {
foreach ($models as $model) {
$value = array_intersect_key($model, $nulls);

Check warning on line 609 in src/ActiveRelationTrait.php

View check run for this annotation

Codecov / codecov/patch

src/ActiveRelationTrait.php#L608-L609

Added lines #L608 - L609 were not covered by tests

$values[] = $v;

if (empty($v)) {
$this->emulateExecution();
if (!empty($value)) {
$values[] = array_combine($attributes, array_merge($nulls, $value));

Check warning on line 612 in src/ActiveRelationTrait.php

View check run for this annotation

Codecov / codecov/patch

src/ActiveRelationTrait.php#L611-L612

Added lines #L611 - L612 were not covered by tests
}
}
}
}

if (!empty($values)) {
$scalarValues = [];
$nonScalarValues = [];
foreach ($values as $value) {
if (is_scalar($value)) {
$scalarValues[] = $value;
} else {
$nonScalarValues[] = $value;
}
}

$scalarValues = array_unique($scalarValues);
$values = [...$scalarValues, ...$nonScalarValues];
if (empty($values)) {
$this->emulateExecution();
$this->andWhere('1=0');
return;
}

$this->andWhere(['in', $attributes, $values]);
Expand Down

0 comments on commit d67403c

Please sign in to comment.