diff --git a/src/AbstractActiveRecord.php b/src/AbstractActiveRecord.php index 580e30150..21ef22c02 100644 --- a/src/AbstractActiveRecord.php +++ b/src/AbstractActiveRecord.php @@ -533,6 +533,10 @@ public function optimisticLock(): string|null */ public function populateRecord(array|object $row): void { + if ($row instanceof ActiveRecordInterface) { + $row = $row->getAttributes(); + } + foreach ($row as $name => $value) { $this->populateAttribute($name, $value); $this->oldAttributes[$name] = $value; diff --git a/src/ArArrayHelper.php b/src/ArArrayHelper.php index 391529ac3..d1b8246e8 100644 --- a/src/ArArrayHelper.php +++ b/src/ArArrayHelper.php @@ -5,11 +5,14 @@ namespace Yiisoft\ActiveRecord; use Closure; +use Traversable; use function array_combine; use function array_key_exists; use function array_map; use function get_object_vars; +use function is_array; +use function iterator_to_array; use function property_exists; use function strrpos; use function substr; @@ -162,4 +165,28 @@ public static function index(array $rows, Closure|string|null $indexBy = null): return $result; } + + /** + * Converts an object into an array. + * + * @param array|object $object The object to be converted into an array. + * + * @return array The array representation of the object. + */ + public static function toArray(array|object $object): array + { + if (is_array($object)) { + return $object; + } + + if ($object instanceof ActiveRecordInterface) { + return $object->getAttributes(); + } + + if ($object instanceof Traversable) { + return iterator_to_array($object); + } + + return get_object_vars($object); + } } diff --git a/src/BaseActiveRecord.php b/src/BaseActiveRecord.php index 65652e026..df4f6305e 100644 --- a/src/BaseActiveRecord.php +++ b/src/BaseActiveRecord.php @@ -162,16 +162,15 @@ public function loadDefaultValues(bool $skipIfSet = true): self public function populateRecord(array|object $row): void { + $row = ArArrayHelper::toArray($row); $columns = $this->getTableSchema()->getColumns(); + $rowColumns = array_intersect_key($row, $columns); - /** @psalm-var array[][] $row */ - foreach ($row as $name => $value) { - if (isset($columns[$name])) { - $row[$name] = $columns[$name]->phpTypecast($value); - } + foreach ($rowColumns as $name => &$value) { + $value = $columns[$name]->phpTypecast($value); } - parent::populateRecord($row); + parent::populateRecord($rowColumns + $row); } public function primaryKey(): array