diff --git a/framework/yii/helpers/base/ArrayHelper.php b/framework/yii/helpers/base/ArrayHelper.php index 07c7155..de64f61 100644 --- a/framework/yii/helpers/base/ArrayHelper.php +++ b/framework/yii/helpers/base/ArrayHelper.php @@ -21,13 +21,56 @@ use yii\base\InvalidParamException; class ArrayHelper { /** - * Converts the object into an array. + * Converts an object or an array of objects into an array. * @param object|array $object the object to be converted into an array + * @param array $properties a mapping from object class names to the properties that need to put into the resulting arrays. + * The properties specified for each class is an array of the following format: + * + * ~~~ + * array( + * 'app\models\Post' => array( + * 'id', + * 'title', + * // the key name in array result => property name + * 'createTime' => 'create_time', + * // the key name in array result => anonymous function + * 'length' => function ($post) { + * return strlen($post->content); + * }, + * ), + * ) + * ~~~ + * + * The result of `ArrayHelper::toArray($post, $properties)` could be like the following: + * + * ~~~ + * array( + * 'id' => 123, + * 'title' => 'test', + * 'createTime' => '2013-01-01 12:00AM', + * 'length' => 301, + * ) + * ~~~ + * * @param boolean $recursive whether to recursively converts properties which are objects into arrays. * @return array the array representation of the object */ - public static function toArray($object, $recursive = true) + public static function toArray($object, $properties = array(), $recursive = true) { + if (!empty($properties) && is_object($object)) { + $className = get_class($object); + if (!empty($properties[$className])) { + $result = array(); + foreach ($properties[$className] as $key => $name) { + if (is_int($key)) { + $result[$name] = $object->$name; + } else { + $result[$key] = static::getValue($object, $name); + } + } + return $result; + } + } if ($object instanceof Arrayable) { $object = $object->toArray(); if (!$recursive) { diff --git a/tests/unit/framework/helpers/ArrayHelperTest.php b/tests/unit/framework/helpers/ArrayHelperTest.php index cfda9ae..3ec80fd 100644 --- a/tests/unit/framework/helpers/ArrayHelperTest.php +++ b/tests/unit/framework/helpers/ArrayHelperTest.php @@ -2,16 +2,61 @@ namespace yiiunit\framework\helpers; +use yii\base\Object; use yii\helpers\ArrayHelper; use yii\test\TestCase; use yii\data\Sort; -class ArrayHelperTest extends TestCase +class Post1 { - public function testMerge() - { + public $id = 23; + public $title = 'tt'; +} +class Post2 extends Object +{ + public $id = 123; + public $content = 'test'; + private $secret = 's'; + public function getSecret() + { + return $this->secret; + } +} +class ArrayHelperTest extends TestCase +{ + public function testToArray() + { + $object = new Post1; + $this->assertEquals(get_object_vars($object), ArrayHelper::toArray($object)); + $object = new Post2; + $this->assertEquals(get_object_vars($object), ArrayHelper::toArray($object)); + + $object1 = new Post1; + $object2 = new Post2; + $this->assertEquals(array( + get_object_vars($object1), + get_object_vars($object2), + ), ArrayHelper::toArray(array( + $object1, + $object2, + ))); + + $object = new Post2; + $this->assertEquals(array( + 'id' => 123, + 'secret' => 's', + '_content' => 'test', + 'length' => 4, + ), ArrayHelper::toArray($object, array( + $object->className() => array( + 'id', 'secret', + '_content' => 'content', + 'length' => function ($post) { + return strlen($post->content); + } + )))); } public function testRemove()