Skip to content

Commit e29c364

Browse files
authored
Merge branch 'WordPress:trunk' into trunk
2 parents e937d7d + 983a066 commit e29c364

4 files changed

Lines changed: 186 additions & 41 deletions

File tree

src/wp-includes/functions.php

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5021,12 +5021,15 @@ function wp_parse_args( $args, $defaults = array() ) {
50215021
*
50225022
* @since 5.1.0
50235023
*
5024-
* @param array|string $input_list List of values.
5025-
* @return array Array of values.
5024+
* @param mixed[]|string $input_list List of values.
5025+
* @return array Array of values. A string is split into a list, while an array
5026+
* keeps its keys, so the result is not necessarily a list.
5027+
* @phpstan-return ( $input_list is string ? list<string> : array<scalar> )
50265028
*/
5027-
function wp_parse_list( $input_list ) {
5029+
function wp_parse_list( $input_list ): array {
50285030
if ( ! is_array( $input_list ) ) {
5029-
return preg_split( '/[\s,]+/', $input_list, -1, PREG_SPLIT_NO_EMPTY );
5031+
$parsed_list = preg_split( '/[\s,]+/', $input_list, -1, PREG_SPLIT_NO_EMPTY );
5032+
return is_array( $parsed_list ) ? $parsed_list : array();
50305033
}
50315034

50325035
// Validate all entries of the list are scalar.
@@ -5041,10 +5044,13 @@ function wp_parse_list( $input_list ) {
50415044
* @since 3.0.0
50425045
* @since 5.1.0 Refactored to use wp_parse_list().
50435046
*
5044-
* @param array|string $input_list List of IDs.
5045-
* @return int[] Sanitized array of IDs.
5047+
* @param mixed[]|string $input_list List of IDs.
5048+
* @return int[] Sanitized array of IDs. May include zero. Keys are preserved
5049+
* from the input and `array_unique()` may leave gaps, so the
5050+
* result is not necessarily a list.
5051+
* @phpstan-return array<non-negative-int>
50465052
*/
5047-
function wp_parse_id_list( $input_list ) {
5053+
function wp_parse_id_list( $input_list ): array {
50485054
$input_list = wp_parse_list( $input_list );
50495055

50505056
return array_unique( array_map( 'absint', $input_list ) );
@@ -5056,13 +5062,27 @@ function wp_parse_id_list( $input_list ) {
50565062
* @since 4.7.0
50575063
* @since 5.1.0 Refactored to use wp_parse_list().
50585064
*
5059-
* @param array|string $input_list List of slugs.
5060-
* @return string[] Sanitized array of slugs.
5065+
* @param mixed[]|string $input_list List of slugs.
5066+
* @return string[] Sanitized array of slugs. May include an empty string. Keys
5067+
* are preserved from the input and `array_unique()` may leave
5068+
* gaps, so the result is not necessarily a list.
50615069
*/
5062-
function wp_parse_slug_list( $input_list ) {
5070+
function wp_parse_slug_list( $input_list ): array {
50635071
$input_list = wp_parse_list( $input_list );
50645072

5065-
return array_unique( array_map( 'sanitize_title', $input_list ) );
5073+
return array_unique(
5074+
array_map(
5075+
'sanitize_title',
5076+
array_map(
5077+
/*
5078+
* Cast booleans, integers, and floats to strings. Non-scalar types
5079+
* (including null) have already been filtered out by wp_parse_list().
5080+
*/
5081+
'strval',
5082+
$input_list
5083+
)
5084+
)
5085+
);
50665086
}
50675087

50685088
/**

tests/phpunit/tests/functions/wpParseIdList.php

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,31 @@ class Tests_Functions_wpParseIdList extends WP_UnitTestCase {
1515
*
1616
* @dataProvider data_wp_parse_id_list
1717
* @dataProvider data_unexpected_input
18+
*
19+
* @param mixed[]|string $input_list
20+
* @param array<non-negative-int> $expected
1821
*/
19-
public function test_wp_parse_id_list( $input_list, $expected ) {
20-
$this->assertSameSets( $expected, wp_parse_id_list( $input_list ) );
22+
public function test_wp_parse_id_list( $input_list, array $expected ): void {
23+
$parsed_list = wp_parse_id_list( $input_list );
24+
$this->assertThat(
25+
$parsed_list,
26+
$this->callback(
27+
static fn ( array $arr ) => array_all(
28+
$arr,
29+
static fn ( $v ) => is_int( $v ) && $v >= 0
30+
)
31+
),
32+
'Array should contain only non-negative ints.'
33+
);
34+
$this->assertSame( $expected, $parsed_list );
2135
}
2236

2337
/**
2438
* Data provider.
2539
*
26-
* @return array[]
40+
* @return array<string, array{ input_list: mixed[]|string, expected: array<non-negative-int> }>
2741
*/
28-
public function data_wp_parse_id_list() {
42+
public function data_wp_parse_id_list(): array {
2943
return array(
3044
'regular' => array(
3145
'input_list' => '1,2,3,4',
@@ -37,7 +51,12 @@ public function data_wp_parse_id_list() {
3751
),
3852
'duplicate id in a string' => array(
3953
'input_list' => '1,2,2,3,4',
40-
'expected' => array( 1, 2, 3, 4 ),
54+
'expected' => array(
55+
0 => 1,
56+
1 => 2,
57+
3 => 3,
58+
4 => 4,
59+
),
4160
),
4261
'duplicate id in an array' => array(
4362
'input_list' => array( '1', '2', '3', '4', '3' ),
@@ -61,9 +80,9 @@ public function data_wp_parse_id_list() {
6180
/**
6281
* Data provider.
6382
*
64-
* @return array[]
83+
* @return array<string, array{ input_list: mixed[]|string, expected: array<non-negative-int> }>
6584
*/
66-
public function data_unexpected_input() {
85+
public function data_unexpected_input(): array {
6786
return array(
6887
'string with commas' => array(
6988
'input_list' => '1,2,string with spaces',
@@ -97,6 +116,25 @@ public function data_unexpected_input() {
97116
'input_list' => array( 1, 2, false ),
98117
'expected' => array( 1, 2, 0 ),
99118
),
119+
'array with array' => array(
120+
'input_list' => array( 1, array(), 2 ),
121+
'expected' => array(
122+
0 => 1,
123+
2 => 2,
124+
),
125+
),
126+
'passed assoc array' => array(
127+
'input_list' => array(
128+
'one' => 1,
129+
'two' => '2',
130+
'three' => '3 is company',
131+
),
132+
'expected' => array(
133+
'one' => 1,
134+
'two' => 2,
135+
'three' => 3,
136+
),
137+
),
100138
);
101139
}
102140
}

tests/phpunit/tests/functions/wpParseList.php

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,62 +13,102 @@ class Tests_Functions_wpParseList extends WP_UnitTestCase {
1313
* @ticket 43977
1414
*
1515
* @dataProvider data_wp_parse_list
16+
*
17+
* @param mixed[]|string $input_list
18+
* @param array<scalar> $expected
1619
*/
17-
public function test_wp_parse_list( $input_list, $expected ) {
18-
$this->assertSameSets( $expected, wp_parse_list( $input_list ) );
20+
public function test_wp_parse_list( $input_list, array $expected ): void {
21+
$parsed_list = wp_parse_list( $input_list );
22+
$this->assertThat(
23+
$parsed_list,
24+
$this->callback(
25+
static fn ( array $arr ) => array_all(
26+
$arr,
27+
static fn ( $v ) => is_scalar( $v )
28+
)
29+
),
30+
'Array should contain only scalars.'
31+
);
32+
$this->assertSame( $expected, $parsed_list );
1933
}
2034

2135
/**
2236
* Data provider.
2337
*
24-
* @return array[]
38+
* @return array<string, array{ input_list: mixed[]|string, expected: array<scalar> }>
2539
*/
26-
public function data_wp_parse_list() {
40+
public function data_wp_parse_list(): array {
2741
return array(
28-
'ids only' => array(
42+
'ids only' => array(
2943
'input_list' => '1,2,3,4',
3044
'expected' => array( '1', '2', '3', '4' ),
3145
),
32-
'slugs only' => array(
46+
'slugs only' => array(
3347
'input_list' => 'apple,banana,carrot,dog',
3448
'expected' => array( 'apple', 'banana', 'carrot', 'dog' ),
3549
),
36-
'ids and slugs' => array(
50+
'ids and slugs' => array(
3751
'input_list' => '1,2,apple,banana',
3852
'expected' => array( '1', '2', 'apple', 'banana' ),
3953
),
40-
'space after comma' => array(
54+
'space after comma' => array(
4155
'input_list' => '1, 2,apple,banana',
4256
'expected' => array( '1', '2', 'apple', 'banana' ),
4357
),
44-
'double comma' => array(
58+
'double comma' => array(
4559
'input_list' => '1,2,apple,,banana',
4660
'expected' => array( '1', '2', 'apple', 'banana' ),
4761
),
48-
'leading comma' => array(
62+
'leading comma' => array(
4963
'input_list' => ',1,2,apple,banana',
5064
'expected' => array( '1', '2', 'apple', 'banana' ),
5165
),
52-
'trailing comma' => array(
66+
'trailing comma' => array(
5367
'input_list' => '1,2,apple,banana,',
5468
'expected' => array( '1', '2', 'apple', 'banana' ),
5569
),
56-
'space before comma' => array(
70+
'space before comma' => array(
5771
'input_list' => '1,2 ,apple,banana',
5872
'expected' => array( '1', '2', 'apple', 'banana' ),
5973
),
60-
'empty string' => array(
74+
'empty string' => array(
6175
'input_list' => '',
6276
'expected' => array(),
6377
),
64-
'comma only' => array(
78+
'comma only' => array(
6579
'input_list' => ',',
6680
'expected' => array(),
6781
),
68-
'double comma only' => array(
82+
'double comma only' => array(
6983
'input_list' => ',,',
7084
'expected' => array(),
7185
),
86+
'passed scalar array' => array(
87+
'input_list' => array( 'foo', true, false, 1, 3.14 ),
88+
'expected' => array( 'foo', true, false, 1, 3.14 ),
89+
),
90+
'passed mixed array' => array(
91+
'input_list' => array( null, 'foo', array(), true, new stdClass(), false, 1, 3.14 ),
92+
'expected' => array(
93+
1 => 'foo',
94+
3 => true,
95+
5 => false,
96+
6 => 1,
97+
7 => 3.14,
98+
),
99+
),
100+
'passed assoc array' => array(
101+
'input_list' => array(
102+
'foo' => 1,
103+
'bar' => true,
104+
'baz' => 3.14,
105+
),
106+
'expected' => array(
107+
'foo' => 1,
108+
'bar' => true,
109+
'baz' => 3.14,
110+
),
111+
),
72112
);
73113
}
74114
}

tests/phpunit/tests/functions/wpParseSlugList.php

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,31 @@ class Tests_Functions_WpParseSlugList extends WP_UnitTestCase {
1515
*
1616
* @dataProvider data_wp_parse_slug_list
1717
* @dataProvider data_unexpected_input
18+
*
19+
* @param mixed[]|string $input_list
20+
* @param array<string> $expected
1821
*/
19-
public function test_wp_parse_slug_list( $input_list, $expected ) {
20-
$this->assertSameSets( $expected, wp_parse_slug_list( $input_list ) );
22+
public function test_wp_parse_slug_list( $input_list, array $expected ): void {
23+
$parsed_list = wp_parse_slug_list( $input_list );
24+
$this->assertThat(
25+
$parsed_list,
26+
$this->callback(
27+
static fn ( array $arr ) => array_all(
28+
$arr,
29+
static fn ( $v ) => is_string( $v )
30+
)
31+
),
32+
'Array should contain only strings.'
33+
);
34+
$this->assertSame( $expected, $parsed_list );
2135
}
2236

2337
/**
2438
* Data provider.
2539
*
26-
* @return array[]
40+
* @return array<string, array{ input_list: mixed[]|string, expected: array<string> }>
2741
*/
28-
public function data_wp_parse_slug_list() {
42+
public function data_wp_parse_slug_list(): array {
2943
return array(
3044
'regular' => array(
3145
'input_list' => 'apple,banana,carrot,dog',
@@ -37,11 +51,21 @@ public function data_wp_parse_slug_list() {
3751
),
3852
'duplicate slug in a string' => array(
3953
'input_list' => 'apple,banana,carrot,carrot,dog',
40-
'expected' => array( 'apple', 'banana', 'carrot', 'dog' ),
54+
'expected' => array(
55+
0 => 'apple',
56+
1 => 'banana',
57+
2 => 'carrot',
58+
4 => 'dog',
59+
),
4160
),
4261
'duplicate slug in an array' => array(
4362
'input_list' => array( 'apple', 'banana', 'carrot', 'carrot', 'dog' ),
44-
'expected' => array( 'apple', 'banana', 'carrot', 'dog' ),
63+
'expected' => array(
64+
0 => 'apple',
65+
1 => 'banana',
66+
2 => 'carrot',
67+
4 => 'dog',
68+
),
4569
),
4670
'string with spaces' => array(
4771
'input_list' => 'apple banana carrot dog',
@@ -51,15 +75,27 @@ public function data_wp_parse_slug_list() {
5175
'input_list' => array( 'apple ', 'banana carrot', 'd o g' ),
5276
'expected' => array( 'apple', 'banana-carrot', 'd-o-g' ),
5377
),
78+
'passed assoc array' => array(
79+
'input_list' => array(
80+
'one' => 'foo',
81+
'two' => 'bar',
82+
'three' => 'baz',
83+
),
84+
'expected' => array(
85+
'one' => 'foo',
86+
'two' => 'bar',
87+
'three' => 'baz',
88+
),
89+
),
5490
);
5591
}
5692

5793
/**
5894
* Data provider.
5995
*
60-
* @return array[]
96+
* @return array<string, array{ input_list: mixed[]|string, expected: array<string> }>
6197
*/
62-
public function data_unexpected_input() {
98+
public function data_unexpected_input(): array {
6399
return array(
64100
'string with commas' => array(
65101
'input_list' => '1,2,string with spaces',
@@ -93,6 +129,17 @@ public function data_unexpected_input() {
93129
'input_list' => array( 1, 2, false ),
94130
'expected' => array( '1', '2', '' ),
95131
),
132+
'array with array' => array(
133+
'input_list' => array( 1, array(), 2 ),
134+
'expected' => array(
135+
0 => '1',
136+
2 => '2',
137+
),
138+
),
139+
'array with tag' => array(
140+
'input_list' => array( 1, '<br>', 2 ),
141+
'expected' => array( '1', '', '2' ),
142+
),
96143
);
97144
}
98145
}

0 commit comments

Comments
 (0)