Skip to content

Commit fbc6af4

Browse files
committed
General: Add polyfills for new PHP 8.5 array functions: array_first and array_last.
This power couple of function is coming in PHP 8.5: array_first and array_last. For more information on these functions, check out the PHP RFC at https://wiki.php.net/rfc/array_first_last. Props tusharbharti, jorbin, peterwilsoncc, mukesh27, johnbillion. Fixes #63853. See #63061. git-svn-id: https://develop.svn.wordpress.org/trunk@60672 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 171a547 commit fbc6af4

File tree

3 files changed

+221
-0
lines changed

3 files changed

+221
-0
lines changed

src/wp-includes/compat.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,48 @@ function array_all( array $array, callable $callback ): bool { // phpcs:ignore U
539539
}
540540
}
541541

542+
if ( ! function_exists( 'array_first' ) ) {
543+
/**
544+
* Polyfill for `array_first()` function added in PHP 8.5.
545+
*
546+
* Returns the first element of an array.
547+
*
548+
* @since 6.9.0
549+
*
550+
* @param array $array The array to get the first element from.
551+
* @return mixed|null The first element of the array, or null if the array is empty.
552+
*/
553+
function array_first( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound
554+
if ( empty( $array ) ) {
555+
return null;
556+
}
557+
558+
foreach ( $array as $value ) {
559+
return $value;
560+
}
561+
}
562+
}
563+
564+
if ( ! function_exists( 'array_last' ) ) {
565+
/**
566+
* Polyfill for `array_last()` function added in PHP 8.5.
567+
*
568+
* Returns the last element of an array.
569+
*
570+
* @since 6.9.0
571+
*
572+
* @param array $array The array to get the last element from.
573+
* @return mixed|null The last element of the array, or null if the array is empty.
574+
*/
575+
function array_last( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound
576+
if ( empty( $array ) ) {
577+
return null;
578+
}
579+
580+
return $array[ array_key_last( $array ) ];
581+
}
582+
}
583+
542584
// IMAGETYPE_AVIF constant is only defined in PHP 8.x or later.
543585
if ( ! defined( 'IMAGETYPE_AVIF' ) ) {
544586
define( 'IMAGETYPE_AVIF', 19 );
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
/**
4+
* @group compat
5+
*
6+
* @covers ::array_first
7+
*/
8+
class Tests_Compat_arrayFirst extends WP_UnitTestCase {
9+
10+
/**
11+
* @ticket 63853
12+
*
13+
* Test that array_first() is always available (either from PHP or WP).
14+
*/
15+
public function test_array_first_availability(): void {
16+
$this->assertTrue( function_exists( 'array_first' ) );
17+
}
18+
19+
/**
20+
* @ticket 63853
21+
*
22+
* @dataProvider data_array_first
23+
*
24+
* @param mixed $expected The value extracted from the given array.
25+
* @param array $arr The array to get the first value from.
26+
*/
27+
public function test_array_first( $expected, $arr ): void {
28+
$this->assertSame( $expected, array_first( $arr ) );
29+
}
30+
31+
32+
/**
33+
* Data provider.
34+
*
35+
* @return array[]
36+
*/
37+
public function data_array_first(): array {
38+
$obj = new \stdClass();
39+
return array(
40+
'string values' => array(
41+
'expected' => 'a',
42+
'arr' => array( 'a', 'b', 'c' ),
43+
),
44+
'associative array' => array(
45+
'expected' => 10,
46+
'arr' => array(
47+
'foo' => 10,
48+
'bar' => 20,
49+
),
50+
),
51+
'empty array' => array(
52+
'expected' => null,
53+
'arr' => array(),
54+
),
55+
'single element array' => array(
56+
'expected' => 42,
57+
'arr' => array( 42 ),
58+
),
59+
'null values' => array(
60+
'expected' => null,
61+
'arr' => array( null, 'b', 'c' ),
62+
),
63+
'objects' => array(
64+
'expected' => $obj,
65+
'arr' => array(
66+
$obj,
67+
1,
68+
2,
69+
),
70+
),
71+
'boolean values' => array(
72+
'expected' => false,
73+
'arr' => array( false, true, 1, 2, 3 ),
74+
),
75+
);
76+
}
77+
78+
/**
79+
* Test that array_first() returns the pointer is not the first element.
80+
*
81+
* @ticket 63853
82+
*/
83+
public function test_array_first_with_end_pointer() {
84+
$arr = array(
85+
'key1' => 'val1',
86+
'key2' => 'val2',
87+
);
88+
// change the pointer to the last element
89+
end( $arr );
90+
91+
$val = array_first( $arr );
92+
$this->assertSame( 'val2', current( $arr ) );
93+
$this->assertSame( 'val1', $val );
94+
}
95+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
/**
4+
* @group compat
5+
*
6+
* @covers ::array_last
7+
*/
8+
class Tests_Compat_arrayLast extends WP_UnitTestCase {
9+
10+
/**
11+
* @ticket 63853
12+
*
13+
* Test that array_last() is always available (either from PHP or WP).
14+
*/
15+
public function test_array_last_availability(): void {
16+
$this->assertTrue( function_exists( 'array_last' ) );
17+
}
18+
19+
/**
20+
* @ticket 63853
21+
*
22+
* @dataProvider data_array_last
23+
*
24+
* @param mixed $expected The expected last value.
25+
* @param array $arr The array to get the last value from.
26+
*/
27+
public function test_array_last( $expected, $arr ): void {
28+
$this->assertSame( $expected, array_last( $arr ) );
29+
}
30+
31+
/**
32+
* Data provider for array_last().
33+
*
34+
* @return array[]
35+
*/
36+
public function data_array_last(): array {
37+
$obj = new \stdClass();
38+
return array(
39+
'string values' => array(
40+
'expected' => 'c',
41+
'arr' => array( 'a', 'b', 'c' ),
42+
),
43+
'associative array' => array(
44+
'expected' => 20,
45+
'arr' => array(
46+
'foo' => 10,
47+
'bar' => 20,
48+
),
49+
),
50+
'empty array' => array(
51+
'expected' => null,
52+
'arr' => array(),
53+
),
54+
'single element array' => array(
55+
'expected' => 42,
56+
'arr' => array( 42 ),
57+
),
58+
'null values' => array(
59+
'expected' => null,
60+
'arr' => array( 'a', 'b', null ),
61+
),
62+
'objects' => array(
63+
'expected' => $obj,
64+
'arr' => array(
65+
1,
66+
2,
67+
$obj,
68+
),
69+
),
70+
'boolean values' => array(
71+
'expected' => false,
72+
'arr' => array( true, false ),
73+
),
74+
'null values in between' => array(
75+
'expected' => 'c',
76+
'arr' => array( 'a', null, 'b', 'c' ),
77+
),
78+
'empty string values' => array(
79+
'expected' => '',
80+
'arr' => array( 'a', 'b', '' ),
81+
),
82+
);
83+
}
84+
}

0 commit comments

Comments
 (0)