Commit 6d8c6e5559 for wordpress.org
commit 6d8c6e5559e8ee637f9f4dc5bc199d131feecdd3
Author: westonruter <westonruter@1a063a9b-81f0-0310-95a4-ce76da25c4cd>
Date: Sat Nov 14 05:15:02 2026 +0000
Posts, Post Types: Accept an array `exclude` in `wp_list_pages()`.
Passing an array of page IDs as the `exclude` argument caused a fatal `TypeError` on PHP 8, since the value was sanitized with `preg_replace()` and split with `explode()`. It is now parsed with `wp_parse_id_list()`, which also accepts the comma-separated string that remains supported for back-compat. The same fix is applied to `wp_page_menu()`, which appended the static front page to `exclude` by string concatenation. The `wp_list_pages_excludes` filter still receives a list of numeric strings, as before.
The `exclude` and `include` arguments are now documented as `int[]`, matching `get_pages()` which receives them. The `include` argument had been typed as an array but described as a comma-separated list. Documenting the array form steers callers toward input that static analysis can check, even though a string is still accepted.
Developed in https://github.com/WordPress/wordpress-develop/pull/13922.
Follow-up to r10115, r10121.
Props sabbir345, westonruter, marian1, irozum, wprashed, therssoftware.
Fixes #66052.
Built from https://develop.svn.wordpress.org/trunk@65527
git-svn-id: http://core.svn.wordpress.org/trunk@64600 1a063a9b-81f0-0310-95a4-ce76da25c4cd
diff --git a/wp-includes/post-template.php b/wp-includes/post-template.php
index 0c2e25112f..9f6559e648 100644
--- a/wp-includes/post-template.php
+++ b/wp-includes/post-template.php
@@ -1274,6 +1274,7 @@ function wp_dropdown_pages( $args = '' ) {
*
* @since 1.5.0
* @since 4.7.0 Added the `item_spacing` argument.
+ * @since 7.2.0 The `exclude` argument now accepts an array of page IDs (a comma-separated list string of IDs remains supported).
*
* @see get_pages()
*
@@ -1290,8 +1291,8 @@ function wp_dropdown_pages( $args = '' ) {
* Accepts -1 (any depth), 0 (all pages), 1 (top-level pages only), and n (pages to
* the given n depth). Default 0.
* @type bool $echo Whether or not to echo the list of pages. Default true.
- * @type string $exclude Comma-separated list of page IDs to exclude. Default empty.
- * @type array $include Comma-separated list of page IDs to include. Default empty.
+ * @type int[] $exclude Array of page IDs to exclude. Default empty array.
+ * @type int[] $include Array of page IDs to include. Default empty array.
* @type string $link_after Text or HTML to follow the page link label. Default null.
* @type string $link_before Text or HTML to precede the page link label. Default null.
* @type string $post_type Post type to query for. Default 'page'.
@@ -1321,7 +1322,7 @@ function wp_list_pages( $args = '' ) {
'show_date' => '',
'date_format' => get_option( 'date_format' ),
'child_of' => 0,
- 'exclude' => '',
+ 'exclude' => array(),
'title_li' => __( 'Pages' ),
'echo' => 1,
'authors' => '',
@@ -1342,11 +1343,8 @@ function wp_list_pages( $args = '' ) {
$output = '';
$current_page = 0;
- // Sanitize, mostly to keep spaces out.
- $parsed_args['exclude'] = preg_replace( '/[^0-9,]/', '', $parsed_args['exclude'] );
-
- // Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array).
- $exclude_array = ( $parsed_args['exclude'] ) ? explode( ',', $parsed_args['exclude'] ) : array();
+ // Allow plugins to filter a list of excluded page IDs, cast to strings for back-compat with the filter's original input.
+ $exclude_array = array_map( 'strval', array_values( array_filter( wp_parse_id_list( $parsed_args['exclude'] ) ) ) );
/**
* Filters the array of pages to exclude from the pages list.
@@ -1354,6 +1352,7 @@ function wp_list_pages( $args = '' ) {
* @since 2.1.0
*
* @param string[] $exclude_array An array of page IDs to exclude.
+ * @phpstan-param list<numeric-string> $exclude_array
*/
$parsed_args['exclude'] = implode( ',', apply_filters( 'wp_list_pages_excludes', $exclude_array ) );
@@ -1414,6 +1413,7 @@ function wp_list_pages( $args = '' ) {
* @since 2.7.0
* @since 4.4.0 Added `menu_id`, `container`, `before`, `after`, and `walker` arguments.
* @since 4.7.0 Added the `item_spacing` argument.
+ * @since 7.2.0 The `exclude` argument now accepts an array of page IDs (a comma-separated list string of IDs remains supported).
*
* @param array|string $args {
* Optional. Array or string of arguments to generate a page menu. See wp_list_pages() for additional arguments.
@@ -1502,12 +1502,8 @@ function wp_page_menu( $args = array() ) {
$menu .= '<li ' . $class . '><a href="' . esc_url( home_url( '/' ) ) . '">' . $args['link_before'] . $text . $args['link_after'] . '</a></li>';
// If the front page is a page, add it to the exclude list.
if ( 'page' === get_option( 'show_on_front' ) ) {
- if ( ! empty( $list_args['exclude'] ) ) {
- $list_args['exclude'] .= ',';
- } else {
- $list_args['exclude'] = '';
- }
- $list_args['exclude'] .= get_option( 'page_on_front' );
+ $list_args['exclude'] = wp_parse_id_list( $list_args['exclude'] ?? array() );
+ $list_args['exclude'][] = (int) get_option( 'page_on_front' );
}
}
diff --git a/wp-includes/version.php b/wp-includes/version.php
index aaf3efbc3b..4c198a1ac6 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
-$wp_version = '7.2-beta5-65526';
+$wp_version = '7.2-beta5-65527';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.