Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions framework/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Yii Framework 2 Change Log
- Bug #20750: Fix `@return` annotation for `yii\console\Controller::runAction()` (mspirkov)
- Bug #20750: Add the missing `@property-write` annotation to `yii\console\Controller` (mspirkov)
- Bug #20751: Fix `@param` annotation for `$param` parameter in `Sort::parseSortParam()` (mspirkov)
- Bug #20781: Fix enum handling in `ArrayHelper::toArray()` (WarLikeLaux)


2.0.54 January 09, 2026
Expand Down
10 changes: 9 additions & 1 deletion framework/helpers/BaseArrayHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,21 @@ public static function toArray($object, $properties = [], $recursive = true)
if (is_array($object)) {
if ($recursive) {
foreach ($object as $key => $value) {
if (is_array($value) || is_object($value)) {
if (PHP_VERSION_ID >= 80100 && $value instanceof \BackedEnum) {
$object[$key] = $value->value;
} elseif (PHP_VERSION_ID >= 80100 && $value instanceof \UnitEnum) {
$object[$key] = $value->name;
} elseif (is_array($value) || is_object($value)) {
$object[$key] = static::toArray($value, $properties, true);
}
}
}

return $object;
} elseif (PHP_VERSION_ID >= 80100 && $object instanceof \BackedEnum) {
return [$object->value];
} elseif (PHP_VERSION_ID >= 80100 && $object instanceof \UnitEnum) {
return [$object->name];
} elseif ($object instanceof \DateTimeInterface) {
return (array)$object;
} elseif (is_object($object)) {
Expand Down
20 changes: 20 additions & 0 deletions phpstan-baseline-7x.neon
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ parameters:
count: 1
path: framework/db/Command.php

-
message: "#^Class BackedEnum not found\\.$#"
count: 2
path: framework/helpers/BaseArrayHelper.php

-
message: "#^Access to property \\$value on an unknown class BackedEnum\\.$#"
count: 2
path: framework/helpers/BaseArrayHelper.php

-
message: "#^Class UnitEnum not found\\.$#"
count: 2
path: framework/helpers/BaseArrayHelper.php

-
message: "#^Access to property \\$name on an unknown class UnitEnum\\.$#"
count: 2
path: framework/helpers/BaseArrayHelper.php

-
message: "#^Call to an undefined method ReflectionType\\:\\:getName\\(\\)\\.$#"
count: 2
Expand Down
60 changes: 60 additions & 0 deletions tests/framework/helpers/ArrayHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
use yii\base\Model;
use yii\data\Sort;
use yii\helpers\ArrayHelper;
use yiiunit\framework\helpers\enums\IntBackedEnum;
use yiiunit\framework\helpers\enums\PureEnum;
use yiiunit\framework\helpers\enums\StringBackedEnum;
use yiiunit\TestCase;

/**
Expand Down Expand Up @@ -132,6 +135,63 @@ public function testToArray(): void
], ArrayHelper::toArray(new DateTime('2021-09-13 15:16:17', new DateTimeZone('UTC'))));
}

public function testToArrayStringBackedEnum(): void
{
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
$this->markTestSkipped('Enums require PHP 8.1+');
}
$this->assertSame(['hearts'], ArrayHelper::toArray(StringBackedEnum::Hearts));
}

public function testToArrayIntBackedEnum(): void
{
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
$this->markTestSkipped('Enums require PHP 8.1+');
}
$this->assertSame([1], ArrayHelper::toArray(IntBackedEnum::Active));
}

public function testToArrayUnitEnum(): void
{
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
$this->markTestSkipped('Enums require PHP 8.1+');
}
$this->assertSame(['Red'], ArrayHelper::toArray(PureEnum::Red));
}

public function testToArrayWithBackedEnumInArray(): void
{
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
$this->markTestSkipped('Enums require PHP 8.1+');
}
$this->assertSame(
['hearts', 'diamonds'],
ArrayHelper::toArray([StringBackedEnum::Hearts, StringBackedEnum::Diamonds])
);
}

public function testToArrayWithUnitEnumInArray(): void
{
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
$this->markTestSkipped('Enums require PHP 8.1+');
}
$this->assertSame(
['Red', 'Blue'],
ArrayHelper::toArray([PureEnum::Red, PureEnum::Blue])
);
}

public function testToArrayWithMixedEnumInArray(): void
{
if (version_compare(PHP_VERSION, '8.1.0', '<')) {
$this->markTestSkipped('Enums require PHP 8.1+');
}
$this->assertSame(
['hearts', 1, 'Red'],
ArrayHelper::toArray([StringBackedEnum::Hearts, IntBackedEnum::Active, PureEnum::Red])
);
}

public function testRemove(): void
{
$array = ['name' => 'b', 'age' => 3];
Expand Down
9 changes: 9 additions & 0 deletions tests/framework/helpers/enums/IntBackedEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace yiiunit\framework\helpers\enums;

enum IntBackedEnum: int
{
case Active = 1;
case Inactive = 0;
}
9 changes: 9 additions & 0 deletions tests/framework/helpers/enums/PureEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace yiiunit\framework\helpers\enums;

enum PureEnum
{
case Red;
case Blue;
}
9 changes: 9 additions & 0 deletions tests/framework/helpers/enums/StringBackedEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace yiiunit\framework\helpers\enums;

enum StringBackedEnum: string
{
case Hearts = 'hearts';
case Diamonds = 'diamonds';
}
Loading