From 3a30bd05926d8c2ef01cfd5a906883f483115e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20W=C3=BCnsch?= Date: Mon, 6 Jul 2026 14:12:02 +0200 Subject: [PATCH 1/6] Coding Standards: Use array_last() to get the last array element. Replace `$array[ count( $array ) - 1 ]` constructs with the `array_last()` function (added in PHP 8.5, polyfilled in compat.php) for improved readability. --- src/wp-admin/includes/ajax-actions.php | 2 +- src/wp-includes/class-wp-block-parser.php | 2 +- src/wp-includes/class-wp-query.php | 4 ++-- src/wp-includes/class-wp-theme-json.php | 4 ++-- src/wp-trackback.php | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index 2af08fba70af9..fa14052db37ee 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -128,7 +128,7 @@ function wp_ajax_ajax_tag_search() { if ( str_contains( $search, ',' ) ) { $search = explode( ',', $search ); - $search = $search[ count( $search ) - 1 ]; + $search = array_last( $search ); } $search = trim( $search ); diff --git a/src/wp-includes/class-wp-block-parser.php b/src/wp-includes/class-wp-block-parser.php index 8c619a7b47f2c..6d02855520f99 100644 --- a/src/wp-includes/class-wp-block-parser.php +++ b/src/wp-includes/class-wp-block-parser.php @@ -342,7 +342,7 @@ public function add_freeform( $length = null ) { * @param int|null $last_offset Last byte offset into document if continuing form earlier output. */ public function add_inner_block( WP_Block_Parser_Block $block, $token_start, $token_length, $last_offset = null ) { - $parent = $this->stack[ count( $this->stack ) - 1 ]; + $parent = array_last( $this->stack ); $parent->block->innerBlocks[] = (array) $block; $html = substr( $this->document, $parent->prev_offset, $token_start - $parent->prev_offset ); diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 437c82f1dd7f1..3b1aabd679c66 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -2417,8 +2417,8 @@ public function get_posts() { if ( '' !== $query_vars['author_name'] ) { if ( str_contains( $query_vars['author_name'], '/' ) ) { $query_vars['author_name'] = explode( '/', $query_vars['author_name'] ); - if ( $query_vars['author_name'][ count( $query_vars['author_name'] ) - 1 ] ) { - $query_vars['author_name'] = $query_vars['author_name'][ count( $query_vars['author_name'] ) - 1 ]; // No trailing slash. + if ( array_last( $query_vars['author_name'] ) ) { + $query_vars['author_name'] = array_last( $query_vars['author_name'] ); // No trailing slash. } else { $query_vars['author_name'] = $query_vars['author_name'][ count( $query_vars['author_name'] ) - 2 ]; // There was a trailing slash. } diff --git a/src/wp-includes/class-wp-theme-json.php b/src/wp-includes/class-wp-theme-json.php index 3c11927d6787b..74bde76b7b054 100644 --- a/src/wp-includes/class-wp-theme-json.php +++ b/src/wp-includes/class-wp-theme-json.php @@ -3576,7 +3576,7 @@ public function get_styles_for_block( $block_metadata ) { */ $is_processing_element = in_array( 'elements', $block_metadata['path'], true ); - $current_element = $is_processing_element ? $block_metadata['path'][ count( $block_metadata['path'] ) - 1 ] : null; + $current_element = $is_processing_element ? array_last( $block_metadata['path'] ) : null; $element_pseudo_allowed = array(); @@ -4264,7 +4264,7 @@ public static function remove_insecure_properties( $theme_json, $origin = 'theme * Get a reference to element name from path. * $metadata['path'] = array( 'styles', 'elements', 'link' ); */ - $current_element = $metadata['path'][ count( $metadata['path'] ) - 1 ]; + $current_element = array_last( $metadata['path'] ); /* * $output is stripped of pseudo selectors. Re-add and process them diff --git a/src/wp-trackback.php b/src/wp-trackback.php index 732ab8b96cd8f..8eabc2c17f88d 100644 --- a/src/wp-trackback.php +++ b/src/wp-trackback.php @@ -47,7 +47,7 @@ function trackback_response( $error = 0, $error_message = '' ) { if ( ! isset( $_GET['tb_id'] ) || ! $_GET['tb_id'] ) { $post_id = explode( '/', $_SERVER['REQUEST_URI'] ); - $post_id = (int) $post_id[ count( $post_id ) - 1 ]; + $post_id = (int) array_last( $post_id ); } $trackback_url = isset( $_POST['url'] ) ? sanitize_url( $_POST['url'] ) : ''; From cf4b58f916194fe3fd47e5ddfbaa4f78b862be87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20W=C3=BCnsch?= Date: Wed, 22 Jul 2026 08:44:25 +0200 Subject: [PATCH 2/6] Coding Standards: Avoid a duplicate array_last() call in WP_Query. Store the result of `array_last()` in a temporary variable instead of calling it twice within the same branch when parsing the author slug from a nice URL. This avoids the repeated (potentially polyfilled) function call and makes the intent clearer. --- src/wp-includes/class-wp-query.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 3b1aabd679c66..960f28a63dddf 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -2417,8 +2417,9 @@ public function get_posts() { if ( '' !== $query_vars['author_name'] ) { if ( str_contains( $query_vars['author_name'], '/' ) ) { $query_vars['author_name'] = explode( '/', $query_vars['author_name'] ); - if ( array_last( $query_vars['author_name'] ) ) { - $query_vars['author_name'] = array_last( $query_vars['author_name'] ); // No trailing slash. + $last_author_name = array_last( $query_vars['author_name'] ); + if ( $last_author_name ) { + $query_vars['author_name'] = $last_author_name; // No trailing slash. } else { $query_vars['author_name'] = $query_vars['author_name'][ count( $query_vars['author_name'] ) - 2 ]; // There was a trailing slash. } From a6e6066d5d9ef9cfc42aa9543e23d5b59c6d273f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20W=C3=BCnsch?= Date: Fri, 24 Jul 2026 09:41:28 +0200 Subject: [PATCH 3/6] Update src/wp-includes/class-wp-block-parser.php Co-authored-by: Weston Ruter --- src/wp-includes/class-wp-block-parser.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-block-parser.php b/src/wp-includes/class-wp-block-parser.php index 6d02855520f99..39c072d71aaea 100644 --- a/src/wp-includes/class-wp-block-parser.php +++ b/src/wp-includes/class-wp-block-parser.php @@ -342,7 +342,10 @@ public function add_freeform( $length = null ) { * @param int|null $last_offset Last byte offset into document if continuing form earlier output. */ public function add_inner_block( WP_Block_Parser_Block $block, $token_start, $token_length, $last_offset = null ) { - $parent = array_last( $this->stack ); + $parent = array_last( $this->stack ); + if ( ! $parent ) { + throw new LogicException( 'The parser stack must not be empty when adding an inner block.' ); + } $parent->block->innerBlocks[] = (array) $block; $html = substr( $this->document, $parent->prev_offset, $token_start - $parent->prev_offset ); From 3dba2c62c7babd5057fa85fc6dd7f597be389f6d Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 30 Jul 2026 12:50:51 -0700 Subject: [PATCH 4/6] Coding Standards: Use array_key_last() in WP_Block_Parser::add_inner_block(). Replace the `array_last()` call and its accompanying `LogicException` guard with `$this->stack[ array_key_last( $this->stack ) ]`. Both internal call sites are already guarded against an empty stack, so the exception was unreachable from core. Since `add_inner_block()` is a public method of a class that can be replaced via the `block_parser_class` filter, throwing a new exception type would have changed behavior for third-party callers, which is out of scope for a coding standards change. Indexing by `array_key_last()` keeps the readability improvement without introducing a nullable into the expression. Co-Authored-By: Claude Opus 5 (1M context) --- src/wp-includes/class-wp-block-parser.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/wp-includes/class-wp-block-parser.php b/src/wp-includes/class-wp-block-parser.php index 39c072d71aaea..ea66e3b51d38d 100644 --- a/src/wp-includes/class-wp-block-parser.php +++ b/src/wp-includes/class-wp-block-parser.php @@ -342,10 +342,7 @@ public function add_freeform( $length = null ) { * @param int|null $last_offset Last byte offset into document if continuing form earlier output. */ public function add_inner_block( WP_Block_Parser_Block $block, $token_start, $token_length, $last_offset = null ) { - $parent = array_last( $this->stack ); - if ( ! $parent ) { - throw new LogicException( 'The parser stack must not be empty when adding an inner block.' ); - } + $parent = $this->stack[ array_key_last( $this->stack ) ]; $parent->block->innerBlocks[] = (array) $block; $html = substr( $this->document, $parent->prev_offset, $token_start - $parent->prev_offset ); From 2613345584a7526d540797d84ece33ce5896dfd2 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 30 Jul 2026 13:14:23 -0700 Subject: [PATCH 5/6] Coding Standards: Use array_last() in the POMO plural forms parser. Replace the two remaining `$stack[ count( $stack ) - 1 ]` reads in `Plural_Forms::parse()` with `array_last( $stack )`. Both sites sit inside `while ( ! empty( $stack ) )` loops, so the stack is guaranteed non-empty and the value read is unchanged. `$stack` is only ever appended to with `$stack[] = ...` and shortened with `array_pop()`, so its keys stay sequential and `array_last()` returns the same element as indexing by `count() - 1`. Co-Authored-By: Claude Opus 5 (1M context) --- src/wp-includes/pomo/plural-forms.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/pomo/plural-forms.php b/src/wp-includes/pomo/plural-forms.php index a604334e88c20..cc31471a0b88d 100644 --- a/src/wp-includes/pomo/plural-forms.php +++ b/src/wp-includes/pomo/plural-forms.php @@ -128,7 +128,7 @@ protected function parse( $str ) { case ')': $found = false; while ( ! empty( $stack ) ) { - $o2 = $stack[ count( $stack ) - 1 ]; + $o2 = array_last( $stack ); if ( '(' !== $o2 ) { $output[] = array( 'op', array_pop( $stack ) ); continue; @@ -163,7 +163,7 @@ protected function parse( $str ) { } while ( ! empty( $stack ) ) { - $o2 = $stack[ count( $stack ) - 1 ]; + $o2 = array_last( $stack ); // Ternary is right-associative in C. if ( '?:' === $operator || '?' === $operator ) { From af4a0301288c7ddb31aec9a4128a03d74b57fabe Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 30 Jul 2026 13:25:16 -0700 Subject: [PATCH 6/6] Coding Standards: Normalize author_name via a local in WP_Query::get_posts(). Read the exploded author name into `$author_name_parts` instead of temporarily storing the array in `$query_vars['author_name']`, so that query var only ever holds a string, and both branches read from the same local. Behavior is unchanged. `$query_vars` is a reference to `$this->query_vars` and feeds `generate_cache_key()`, so the value it ends up with matters: both branches still assign it exactly as before, and only the intervening array assignment -- which every path overwrote two lines later -- is gone. The loose `if ( $last_part )` check is kept deliberately; a strict `'' !== $last_part` would change the result for an author name such as `a/0`. Co-Authored-By: Claude Opus 5 (1M context) --- src/wp-includes/class-wp-query.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/class-wp-query.php b/src/wp-includes/class-wp-query.php index 655e89f8c83bd..fc698b343e138 100644 --- a/src/wp-includes/class-wp-query.php +++ b/src/wp-includes/class-wp-query.php @@ -2430,12 +2430,12 @@ public function get_posts() { if ( '' !== $query_vars['author_name'] ) { if ( str_contains( $query_vars['author_name'], '/' ) ) { - $query_vars['author_name'] = explode( '/', $query_vars['author_name'] ); - $last_author_name = array_last( $query_vars['author_name'] ); - if ( $last_author_name ) { - $query_vars['author_name'] = $last_author_name; // No trailing slash. + $author_name_parts = explode( '/', $query_vars['author_name'] ); + $last_part = array_last( $author_name_parts ); + if ( $last_part ) { + $query_vars['author_name'] = $last_part; // No trailing slash. } else { - $query_vars['author_name'] = $query_vars['author_name'][ count( $query_vars['author_name'] ) - 2 ]; // There was a trailing slash. + $query_vars['author_name'] = $author_name_parts[ count( $author_name_parts ) - 2 ]; // There was a trailing slash. } } $query_vars['author_name'] = sanitize_title_for_query( $query_vars['author_name'] );