diff --git a/src/wp-includes/compat.php b/src/wp-includes/compat.php index b95275455c..2a8664c065 100644 --- a/src/wp-includes/compat.php +++ b/src/wp-includes/compat.php @@ -375,6 +375,48 @@ if ( ! function_exists( 'is_iterable' ) ) { } } +if ( ! function_exists( 'array_key_first' ) ) { + /** + * Polyfill for array_key_first() function added in PHP 7.3. + * + * Get the first key of the given array without affecting + * the internal array pointer. + * + * @since 5.9.0 + * + * @param array $arr An array. + * @return string|int|null The first key of array if the array + * is not empty; `null` otherwise. + */ + function array_key_first( array $arr ) { + foreach ( $arr as $key => $value ) { + return $key; + } + } +} + +if ( ! function_exists( 'array_key_last' ) ) { + /** + * Polyfill for `array_key_last()` function added in PHP 7.3. + * + * Get the last key of the given array without affecting the + * internal array pointer. + * + * @since 5.9.0 + * + * @param array $arr An array. + * @return string|int|null The last key of array if the array + *. is not empty; `null` otherwise. + */ + function array_key_last( array $arr ) { + if ( empty( $arr ) ) { + return null; + } + end( $arr ); + return key( $arr ); + } +} + // IMAGETYPE_WEBP constant is only defined in PHP 7.1 or later. if ( ! defined( 'IMAGETYPE_WEBP' ) ) { define( 'IMAGETYPE_WEBP', 18 ); diff --git a/tests/phpunit/tests/compat/arrayKeyFirst.php b/tests/phpunit/tests/compat/arrayKeyFirst.php new file mode 100644 index 0000000000..613845aba0 --- /dev/null +++ b/tests/phpunit/tests/compat/arrayKeyFirst.php @@ -0,0 +1,76 @@ +assertTrue( function_exists( 'array_key_first' ) ); + } + + /** + * @dataProvider data_array_key_first + * + * @ticket 45055 + * + * @param bool $expected The value of the key extracted to extracted from given array. + * @param array $arr The array to get first key from. + */ + public function test_array_key_first( $expected, $arr ) { + if ( ! function_exists( 'array_key_first' ) ) { + $this->markTestSkipped( 'array_key_first() is not available.' ); + } else { + $this->assertSame( + $expected, + array_key_first( $arr ) + ); + } + + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_array_key_first() { + return array( + 'string key' => array( + 'expected' => 'key1', + 'arr' => array( + 'key1' => 'val1', + 'key2' => 'val2', + ), + ), + 'int key' => array( + 'expected' => 99, + 'arr' => array( + 99 => 'val1', + 1 => 'val2', + ), + ), + 'no key' => array( + 'expected' => 0, + 'arr' => array( 'val1', 'val2' ), + ), + 'multi array' => array( + 'expected' => 99, + 'arr' => array( + 99 => array( 22 => 'val1' ), + 1 => 'val2', + ), + ), + 'empty array' => array( + 'expected' => null, + 'arr' => array(), + ), + ); + } +} diff --git a/tests/phpunit/tests/compat/arrayKeyLast.php b/tests/phpunit/tests/compat/arrayKeyLast.php new file mode 100644 index 0000000000..77510c8320 --- /dev/null +++ b/tests/phpunit/tests/compat/arrayKeyLast.php @@ -0,0 +1,81 @@ +assertTrue( function_exists( 'array_key_last' ) ); + } + + /** + * @dataProvider data_array_key_last + * + * @ticket 45055 + * + * @param bool $expected The value of the key extracted to extracted from given array. + * @param array $arr The array to get last key from. + */ + public function test_array_key_last( $expected, $arr ) { + if ( ! function_exists( 'array_key_last' ) ) { + $this->markTestSkipped( 'array_key_last() is not available.' ); + } else { + $this->assertSame( $expected, array_key_last( $arr ) ); + } + } + + /** + * Data provider for test_array_key_last(). + * + * @return array + */ + public function data_array_key_last() { + return array( + 'string key' => array( + 'expected' => 'key2', + 'arr' => array( + 'key1' => 'val1', + 'key2' => 'val2', + ), + ), + 'int key' => array( + 'expected' => 1, + 'arr' => array( + 99 => 'val1', + 1 => 'val2', + ), + ), + 'no key' => array( + 'expected' => 1, + 'arr' => array( 'val1', 'val2' ), + ), + 'multi array' => array( + 'expected' => 1, + 'arr' => array( + 99 => array( 22 => 'val1' ), + 1 => 'val2', + ), + ), + 'mixed keys' => array( + 'expected' => 1, + 'arr' => array( + 'val1', + 'key2' => 'val2', + 'val3', + ), + ), + 'empty array' => array( + 'expected' => null, + 'arr' => array(), + ), + ); + } +}