diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 94d6de3eb5..bee66303df 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -2882,21 +2882,51 @@ function wp_list_filter( $list, $args = array(), $operator = 'AND' ) { /** * Pluck a certain field out of each object in a list. * + * This has the same functionality and prototype of + * array_column() (PHP 5.5) but also supports objects. + * * @since 3.1.0 * * @param array $list A list of objects or arrays * @param int|string $field A field from the object to place instead of the entire object + * @param int|string $index_key A field from the object to use as keys for the new array * @return array */ -function wp_list_pluck( $list, $field ) { - foreach ( $list as $key => $value ) { - if ( is_object( $value ) ) - $list[ $key ] = $value->$field; - else - $list[ $key ] = $value[ $field ]; +function wp_list_pluck( $list, $field, $index_key = null ) { + if ( ! $index_key ) { + // This is simple. Could at some point wrap array_column() + // if we knew we had an array of arrays. + foreach ( $list as $key => $value ) { + if ( is_object( $value ) ) { + $list[ $key ] = $value->$field; + } else { + $list[ $key ] = $value[ $field ]; + } + } + return $list; } - return $list; + // When index_key is not set for a particular item, + // push the value to the end of the stack. + // This is how array_column() behaves. + $newlist = array(); + foreach ( $list as $value ) { + if ( is_object( $value ) ) { + if ( isset( $value->$index_key ) ) { + $newlist[ $value->$index_key ] = $value->$field; + } else { + $newlist[] = $value->$field; + } + } else { + if ( isset( $value[ $index_key ] ) ) { + $newlist[ $value[ $index_key ] ] = $value[ $field ]; + } else { + $newlist[] = $value[ $field ]; + } + } + } + + return $newlist; } /** diff --git a/tests/phpunit/tests/functions/listFilter.php b/tests/phpunit/tests/functions/listFilter.php index ac1847b5a9..9fe640a261 100644 --- a/tests/phpunit/tests/functions/listFilter.php +++ b/tests/phpunit/tests/functions/listFilter.php @@ -11,9 +11,9 @@ class Tests_Functions_ListFilter extends WP_UnitTestCase { function setUp() { parent::setUp(); - $this->array_list['foo'] = array( 'name' => 'foo', 'field1' => true, 'field2' => true, 'field3' => true, 'field4' => array( 'red' ) ); - $this->array_list['bar'] = array( 'name' => 'bar', 'field1' => true, 'field2' => true, 'field3' => false, 'field4' => array( 'green' ) ); - $this->array_list['baz'] = array( 'name' => 'baz', 'field1' => true, 'field2' => false, 'field3' => false, 'field4' => array( 'blue' ) ); + $this->array_list['foo'] = array( 'name' => 'foo', 'id' => 'f', 'field1' => true, 'field2' => true, 'field3' => true, 'field4' => array( 'red' ) ); + $this->array_list['bar'] = array( 'name' => 'bar', 'id' => 'b', 'field1' => true, 'field2' => true, 'field3' => false, 'field4' => array( 'green' ) ); + $this->array_list['baz'] = array( 'name' => 'baz', 'id' => 'z', 'field1' => true, 'field2' => false, 'field3' => false, 'field4' => array( 'blue' ) ); foreach ( $this->array_list as $key => $value ) { $this->object_list[ $key ] = (object) $value; } @@ -66,6 +66,50 @@ class Tests_Functions_ListFilter extends WP_UnitTestCase { $this->assertEquals( array( 'foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz' ) , $list ); } + /** + * @ticket 28666 + */ + function test_wp_list_pluck_index_key() { + $list = wp_list_pluck( $this->array_list, 'name', 'id' ); + $this->assertEquals( array( 'f' => 'foo', 'b' => 'bar', 'z' => 'baz' ), $list ); + } + + /** + * @ticket 28666 + */ + function test_wp_list_pluck_object_index_key() { + $list = wp_list_pluck( $this->object_list, 'name', 'id' ); + $this->assertEquals( array( 'f' => 'foo', 'b' => 'bar', 'z' => 'baz' ), $list ); + } + + /** + * @ticket 28666 + */ + function test_wp_list_pluck_missing_index_key() { + $list = wp_list_pluck( $this->array_list, 'name', 'nonexistent' ); + $this->assertEquals( array( 0 => 'foo', 1 => 'bar', 2 => 'baz' ), $list ); + } + + /** + * @ticket 28666 + */ + function test_wp_list_pluck_partial_missing_index_key() { + $array_list = $this->array_list; + unset( $array_list[ 'bar']['id'] ); + $list = wp_list_pluck( $array_list, 'name', 'id' ); + $this->assertEquals( array( 'f' => 'foo', 0 => 'bar', 'z' => 'baz' ), $list ); + } + + /** + * @ticket 28666 + */ + function test_wp_list_pluck_mixed_index_key() { + $mixed_list = $this->array_list; + $mixed_list['bar'] = (object) $mixed_list['bar']; + $list = wp_list_pluck( $mixed_list, 'name', 'id' ); + $this->assertEquals( array( 'f' => 'foo', 'b' => 'bar', 'z' => 'baz' ), $list ); + } + function test_filter_object_list_nested_array_and() { $list = wp_filter_object_list( $this->object_list, array( 'field4' => array( 'blue' ) ), 'AND' ); $this->assertEquals( 1, count( $list ) );