Skip to content

Commit 6fea443

Browse files
committed
General: Introduce polyfills for new array related functions in PHP 8.4.
PHP 8.4 introduced four new functions to provide a common way to more easily perform common operations on arrays. - `array_find()`: https://www.php.net/manual/en/function.array-find.php - `array_find_key()`: https://www.php.net/manual/en/function.array-find-key.php - `array_all()`: https://www.php.net/manual/en/function.array-all.php - `array_any()`: https://www.php.net/manual/en/function.array-any.php These functions are now polyfilled making them available on all supported versions of PHP (currently 7.2+). Props Soean, swissspidy, TobiasBg, ayeshrajans, mukesh27, joemcgill. Fixes #62558. git-svn-id: https://develop.svn.wordpress.org/trunk@59783 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 712a7af commit 6fea443

File tree

5 files changed

+410
-0
lines changed

5 files changed

+410
-0
lines changed

src/wp-includes/compat.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,98 @@ function str_ends_with( $haystack, $needle ) {
549549
}
550550
}
551551

552+
if ( ! function_exists( 'array_find' ) ) {
553+
/**
554+
* Polyfill for `array_find()` function added in PHP 8.4.
555+
*
556+
* Searches an array for the first element that passes a given callback.
557+
*
558+
* @since 6.8.0
559+
*
560+
* @param array $array The array to search.
561+
* @param callable $callback The callback to run for each element.
562+
* @return mixed|null The first element in the array that passes the `$callback`, otherwise null.
563+
*/
564+
function array_find( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound
565+
foreach ( $array as $key => $value ) {
566+
if ( $callback( $value, $key ) ) {
567+
return $value;
568+
}
569+
}
570+
571+
return null;
572+
}
573+
}
574+
575+
if ( ! function_exists( 'array_find_key' ) ) {
576+
/**
577+
* Polyfill for `array_find_key()` function added in PHP 8.4.
578+
*
579+
* Searches an array for the first key that passes a given callback.
580+
*
581+
* @since 6.8.0
582+
*
583+
* @param array $array The array to search.
584+
* @param callable $callback The callback to run for each element.
585+
* @return int|string|null The first key in the array that passes the `$callback`, otherwise null.
586+
*/
587+
function array_find_key( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound
588+
foreach ( $array as $key => $value ) {
589+
if ( $callback( $value, $key ) ) {
590+
return $key;
591+
}
592+
}
593+
594+
return null;
595+
}
596+
}
597+
598+
if ( ! function_exists( 'array_any' ) ) {
599+
/**
600+
* Polyfill for `array_any()` function added in PHP 8.4.
601+
*
602+
* Checks if any element of an array passes a given callback.
603+
*
604+
* @since 6.8.0
605+
*
606+
* @param array $array The array to check.
607+
* @param callable $callback The callback to run for each element.
608+
* @return bool True if any element in the array passes the `$callback`, otherwise false.
609+
*/
610+
function array_any( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound
611+
foreach ( $array as $key => $value ) {
612+
if ( $callback( $value, $key ) ) {
613+
return true;
614+
}
615+
}
616+
617+
return false;
618+
}
619+
}
620+
621+
if ( ! function_exists( 'array_all' ) ) {
622+
/**
623+
* Polyfill for `array_all()` function added in PHP 8.4.
624+
*
625+
* Checks if all elements of an array pass a given callback.
626+
*
627+
* @since 6.8.0
628+
*
629+
* @param array $array The array to check.
630+
* @param callable $callback The callback to run for each element.
631+
* @return bool True if all elements in the array pass the `$callback`, otherwise false.
632+
*/
633+
function array_all( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound
634+
foreach ( $array as $key => $value ) {
635+
if ( ! $callback( $value, $key ) ) {
636+
return false;
637+
}
638+
}
639+
640+
return true;
641+
}
642+
}
643+
552644
// IMAGETYPE_AVIF constant is only defined in PHP 8.x or later.
553645
if ( ! defined( 'IMAGETYPE_AVIF' ) ) {
554646
define( 'IMAGETYPE_AVIF', 19 );
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/**
4+
* @group compat
5+
*
6+
* @covers ::array_all
7+
*/
8+
class Test_Compat_arrayAll extends WP_UnitTestCase {
9+
10+
/**
11+
* Test that array_all() is always available (either from PHP or WP).
12+
*
13+
* @ticket 62558
14+
*/
15+
public function test_array_all_availability() {
16+
$this->assertTrue( function_exists( 'array_all' ) );
17+
}
18+
19+
/**
20+
* @dataProvider data_array_all
21+
*
22+
* @ticket 62558
23+
*
24+
* @param bool $expected The expected value.
25+
* @param array $arr The array.
26+
* @param callable $callback The callback.
27+
*/
28+
public function test_array_all( bool $expected, array $arr, callable $callback ) {
29+
$this->assertSame( $expected, array_all( $arr, $callback ) );
30+
}
31+
32+
/**
33+
* Data provider.
34+
*
35+
* @return array[]
36+
*/
37+
public function data_array_all(): array {
38+
return array(
39+
'empty array' => array(
40+
'expected' => true,
41+
'arr' => array(),
42+
'callback' => function ( $value ) {
43+
return 1 === $value;
44+
},
45+
),
46+
'no match' => array(
47+
'expected' => false,
48+
'arr' => array( 2, 3, 4 ),
49+
'callback' => function ( $value ) {
50+
return 1 === $value;
51+
},
52+
),
53+
'not all match' => array(
54+
'expected' => false,
55+
'arr' => array( 2, 3, 4 ),
56+
'callback' => function ( $value ) {
57+
return 0 === $value % 2;
58+
},
59+
),
60+
'match' => array(
61+
'expected' => true,
62+
'arr' => array( 2, 4, 6 ),
63+
'callback' => function ( $value ) {
64+
return 0 === $value % 2;
65+
},
66+
),
67+
'key match' => array(
68+
'expected' => true,
69+
'arr' => array(
70+
'a' => 2,
71+
'b' => 4,
72+
'c' => 6,
73+
),
74+
'callback' => function ( $value, $key ) {
75+
return strlen( $key ) === 1;
76+
},
77+
),
78+
);
79+
}
80+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
/**
4+
* @group compat
5+
*
6+
* @covers ::array_any
7+
*/
8+
class Test_Compat_arrayAny extends WP_UnitTestCase {
9+
10+
/**
11+
* Test that array_any() is always available (either from PHP or WP).
12+
*
13+
* @ticket 62558
14+
*/
15+
public function test_array_any_availability() {
16+
$this->assertTrue( function_exists( 'array_any' ) );
17+
}
18+
19+
/**
20+
* @dataProvider data_array_any
21+
*
22+
* @ticket 62558
23+
*
24+
* @param bool $expected The expected value.
25+
* @param array $arr The array.
26+
* @param callable $callback The callback.
27+
*/
28+
public function test_array_any( bool $expected, array $arr, callable $callback ) {
29+
$this->assertSame( $expected, array_any( $arr, $callback ) );
30+
}
31+
32+
/**
33+
* Data provider.
34+
*
35+
* @return array[]
36+
*/
37+
public function data_array_any(): array {
38+
return array(
39+
'empty array' => array(
40+
'expected' => false,
41+
'arr' => array(),
42+
'callback' => function ( $value ) {
43+
return 1 === $value;
44+
},
45+
),
46+
'no match' => array(
47+
'expected' => false,
48+
'arr' => array( 2, 3, 4 ),
49+
'callback' => function ( $value ) {
50+
return 1 === $value;
51+
},
52+
),
53+
'match' => array(
54+
'expected' => true,
55+
'arr' => array( 2, 3, 4 ),
56+
'callback' => function ( $value ) {
57+
return 3 === $value;
58+
},
59+
),
60+
'key match' => array(
61+
'expected' => true,
62+
'arr' => array(
63+
'a' => 2,
64+
'b' => 3,
65+
'c' => 4,
66+
),
67+
'callback' => function ( $value, $key ) {
68+
return 'c' === $key;
69+
},
70+
),
71+
);
72+
}
73+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
/**
4+
* @group compat
5+
*
6+
* @covers ::array_find
7+
*/
8+
class Tests_Compat_arrayFind extends WP_UnitTestCase {
9+
10+
/**
11+
* Test that array_find() is always available (either from PHP or WP).
12+
*
13+
* @ticket 62558
14+
*/
15+
public function test_array_find_availability() {
16+
$this->assertTrue( function_exists( 'array_find' ) );
17+
}
18+
19+
/**
20+
* @dataProvider data_array_find
21+
*
22+
* @ticket 62558
23+
*
24+
* @param mixed $expected The expected value.
25+
* @param array $arr The array.
26+
* @param callable $callback The needle.
27+
*/
28+
public function test_array_find( $expected, array $arr, callable $callback ) {
29+
$this->assertSame( $expected, array_find( $arr, $callback ) );
30+
}
31+
32+
/**
33+
* Data provider.
34+
*
35+
* @return array[]
36+
*/
37+
public function data_array_find(): array {
38+
return array(
39+
'empty array' => array(
40+
'expected' => null,
41+
'arr' => array(),
42+
'callback' => function ( $value ) {
43+
return 1 === $value;
44+
},
45+
),
46+
'no match' => array(
47+
'expected' => null,
48+
'arr' => array( 2, 3, 4 ),
49+
'callback' => function ( $value ) {
50+
return 1 === $value;
51+
},
52+
),
53+
'match' => array(
54+
'expected' => 3,
55+
'arr' => array( 2, 3, 4 ),
56+
'callback' => function ( $value ) {
57+
return 3 === $value;
58+
},
59+
),
60+
'key match' => array(
61+
'expected' => 3,
62+
'arr' => array(
63+
'a' => 2,
64+
'b' => 3,
65+
'c' => 4,
66+
),
67+
'callback' => function ( $value ) {
68+
return 3 === $value;
69+
},
70+
),
71+
'two callback matches' => array(
72+
'expected' => 2,
73+
'arr' => array( 2, 3, 4 ),
74+
'callback' => function ( $value ) {
75+
return 0 === $value % 2;
76+
},
77+
),
78+
79+
);
80+
}
81+
}

0 commit comments

Comments
 (0)