From 6d835969801f10d2564b715cb2078f4580027763 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 24 Feb 2026 21:48:31 -0800 Subject: [PATCH 01/15] Ignore errors in src/wp-includes/build which currently come the Gutenberg build --- tests/phpstan/base.neon | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/phpstan/base.neon b/tests/phpstan/base.neon index 347c2198ae953..8260f02b3aa88 100644 --- a/tests/phpstan/base.neon +++ b/tests/phpstan/base.neon @@ -105,6 +105,8 @@ parameters: - ../../src/wp-includes/deprecated.php - ../../src/wp-includes/ms-deprecated.php - ../../src/wp-includes/pluggable-deprecated.php + # These files are currently pulled in from Gutenberg, but maybe not long-term. See . + - ../../src/wp-includes/build # These files are sourced by wordpress/gutenberg in `tools/release/sync-stable-blocks.js`. - ../../src/wp-includes/blocks # Third-party libraries. From 5dec036584b5d7811c139d74fc542dfe845c8876 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 24 Feb 2026 22:37:27 -0800 Subject: [PATCH 02/15] Bump phpstan to 2.1.40 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 17f53c2116f71..649a3d429324c 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "squizlabs/php_codesniffer": "3.13.5", "wp-coding-standards/wpcs": "~3.3.0", "phpcompatibility/phpcompatibility-wp": "~2.1.3", - "phpstan/phpstan": "2.1.39", + "phpstan/phpstan": "2.1.40", "yoast/phpunit-polyfills": "^1.1.0" }, "config": { From 593a10ca6bf9b9fe148dc56eb6b5e72fe9fcbe18 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 3 Mar 2026 18:07:14 -0800 Subject: [PATCH 03/15] Bump PHPStan to level 1 --- phpstan.neon.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index e74e6ec1a441b..186eac7f59505 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -14,7 +14,7 @@ includes: parameters: # https://phpstan.org/user-guide/rule-levels - level: 0 + level: 1 reportUnmatchedIgnoredErrors: true ignoreErrors: From 22de4b6588239441a9d0852b67820cda399af2f8 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 3 Mar 2026 18:09:21 -0800 Subject: [PATCH 04/15] Ignore variable.undefined errors since too noisy Co-authored-by: Dovid Levine --- phpstan.neon.dist | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 186eac7f59505..38dd9c63098d0 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -34,3 +34,8 @@ parameters: identifier: function.inner path: src/wp-includes/canonical.php count: 1 + + # Level 1: + - # These are too noisy at the moment. + identifier: variable.undefined + message: '#Variable \$[a-zA-Z0-9_]+ might not be defined\.#' From cb8db153dddbb84bb7dc3920e5aa7c12b0154946 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 3 Mar 2026 18:10:20 -0800 Subject: [PATCH 05/15] Regenerate baseline for level 1 --- tests/phpstan/baseline.php | 190 ++++++++++++++++++++++++++++++++++++- 1 file changed, 189 insertions(+), 1 deletion(-) diff --git a/tests/phpstan/baseline.php b/tests/phpstan/baseline.php index 646cbdbef630c..d0443d8bbf7b1 100644 --- a/tests/phpstan/baseline.php +++ b/tests/phpstan/baseline.php @@ -1,3 +1,191 @@ '#^Call to function compact\\(\\) contains possibly undefined variable \\$comment_author\\.$#', + 'identifier' => 'variable.undefined', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/includes/ajax-actions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to function compact\\(\\) contains possibly undefined variable \\$comment_author_email\\.$#', + 'identifier' => 'variable.undefined', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/includes/ajax-actions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to function compact\\(\\) contains possibly undefined variable \\$comment_author_url\\.$#', + 'identifier' => 'variable.undefined', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/includes/ajax-actions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Call to function compact\\(\\) contains possibly undefined variable \\$user_id\\.$#', + 'identifier' => 'variable.undefined', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/includes/ajax-actions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$_POST in isset\\(\\) always exists and is not nullable\\.$#', + 'identifier' => 'isset.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/includes/class-custom-image-header.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constructor of class WP_Filesystem_Direct has an unused parameter \\$arg\\.$#', + 'identifier' => 'constructor.unusedParameter', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/includes/class-wp-filesystem-direct.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$class in empty\\(\\) always exists and is always falsy\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/includes/class-wp-posts-list-table.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$_POST in isset\\(\\) always exists and is not nullable\\.$#', + 'identifier' => 'isset.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/includes/media.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$parent_file in empty\\(\\) always exists and is not falsy\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-admin/themes.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constant HEADER_IMAGE_HEIGHT not found\\.$#', + 'identifier' => 'constant.notFound', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/functions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', + 'identifier' => 'constant.notFound', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/functions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constant HEADER_TEXTCOLOR not found\\.$#', + 'identifier' => 'constant.notFound', + 'count' => 2, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/functions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', + 'identifier' => 'constant.notFound', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/header.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', + 'identifier' => 'constant.notFound', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/showcase.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Function twentyseventeen_edit_link invoked with 1 parameter, 0 required\\.$#', + 'identifier' => 'arguments.count', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyseventeen/template-parts/page/content-front-page-panels.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Function twentyseventeen_edit_link invoked with 1 parameter, 0 required\\.$#', + 'identifier' => 'arguments.count', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyseventeen/template-parts/page/content-front-page.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Function twentyseventeen_edit_link invoked with 1 parameter, 0 required\\.$#', + 'identifier' => 'arguments.count', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyseventeen/template-parts/page/content-page.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constant HEADER_IMAGE_HEIGHT not found\\.$#', + 'identifier' => 'constant.notFound', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyten/functions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', + 'identifier' => 'constant.notFound', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyten/functions.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', + 'identifier' => 'constant.notFound', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-content/themes/twentyten/header.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Function wp_cache_switch_to_blog_fallback invoked with 1 parameter, 0 required\\.$#', + 'identifier' => 'arguments.count', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/cache-compat.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$addl_path in empty\\(\\) always exists and is always falsy\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/canonical.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$namespace in isset\\(\\) always exists and is not nullable\\.$#', + 'identifier' => 'isset.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/class-wp-block-parser.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$block_type in empty\\(\\) always exists and is not falsy\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/class-wp-block-supports.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$loader in isset\\(\\) always exists and is not nullable\\.$#', + 'identifier' => 'isset.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/class-wp-oembed.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$search in empty\\(\\) always exists and is not falsy\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/class-wp-query.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$status_type_clauses in empty\\(\\) always exists and is not falsy\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/class-wp-query.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$deprecated in empty\\(\\) always exists and is always falsy\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/pluggable.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$schema in empty\\(\\) is never defined\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$the_parent in empty\\(\\) always exists and is not falsy\\.$#', + 'identifier' => 'empty.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/taxonomy.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Variable \\$s in isset\\(\\) is never defined\\.$#', + 'identifier' => 'isset.variable', + 'count' => 1, + 'path' => __DIR__ . '/../../src/wp-includes/template.php', +]; + +return ['parameters' => ['ignoreErrors' => $ignoreErrors]]; From d3dd8ecd6306dabce1c12cccb94044f0595fe22e Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 3 Mar 2026 19:08:39 -0800 Subject: [PATCH 06/15] Remove unused parameter for WP_Filesystem_Direct constructor --- src/wp-admin/includes/class-wp-filesystem-direct.php | 4 +--- tests/phpstan/baseline.php | 6 ------ 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/wp-admin/includes/class-wp-filesystem-direct.php b/src/wp-admin/includes/class-wp-filesystem-direct.php index a4b197c15229f..34862a661d321 100644 --- a/src/wp-admin/includes/class-wp-filesystem-direct.php +++ b/src/wp-admin/includes/class-wp-filesystem-direct.php @@ -19,10 +19,8 @@ class WP_Filesystem_Direct extends WP_Filesystem_Base { * Constructor. * * @since 2.5.0 - * - * @param mixed $arg Not used. */ - public function __construct( $arg ) { + public function __construct() { $this->method = 'direct'; $this->errors = new WP_Error(); } diff --git a/tests/phpstan/baseline.php b/tests/phpstan/baseline.php index d0443d8bbf7b1..d656589f4a069 100644 --- a/tests/phpstan/baseline.php +++ b/tests/phpstan/baseline.php @@ -31,12 +31,6 @@ 'count' => 1, 'path' => __DIR__ . '/../../src/wp-admin/includes/class-custom-image-header.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Constructor of class WP_Filesystem_Direct has an unused parameter \\$arg\\.$#', - 'identifier' => 'constructor.unusedParameter', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-admin/includes/class-wp-filesystem-direct.php', -]; $ignoreErrors[] = [ 'message' => '#^Variable \\$class in empty\\(\\) always exists and is always falsy\\.$#', 'identifier' => 'empty.variable', From bf92684d1a5041de6a67abd1ce7b3ce38dcf3b05 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 3 Mar 2026 19:17:57 -0800 Subject: [PATCH 07/15] Add theme constants to config to address constant.notFound errors Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- tests/phpstan/base.neon | 7 ++++++ tests/phpstan/baseline.php | 48 ------------------------------------- tests/phpstan/bootstrap.php | 9 +++++++ 3 files changed, 16 insertions(+), 48 deletions(-) diff --git a/tests/phpstan/base.neon b/tests/phpstan/base.neon index 8260f02b3aa88..7bfe9d6eff3df 100644 --- a/tests/phpstan/base.neon +++ b/tests/phpstan/base.neon @@ -25,6 +25,8 @@ parameters: - ALLOW_SUBDIRECTORY_INSTALL - AUTH_SALT - AUTOMATIC_UPDATER_DISABLED + - BACKGROUND_COLOR + - BACKGROUND_IMAGE - COOKIEPATH - CUSTOM_TAGS - DISALLOW_FILE_EDIT @@ -32,8 +34,13 @@ parameters: - EMPTY_TRASH_DAYS - ENFORCE_GZIP - FORCE_SSL_LOGIN + - HEADER_IMAGE + - HEADER_IMAGE_HEIGHT + - HEADER_IMAGE_WIDTH + - HEADER_TEXTCOLOR - MEDIA_TRASH - MULTISITE + - NO_HEADER_TEXT - NOBLOGREDIRECT - SAVEQUERIES - SCRIPT_DEBUG diff --git a/tests/phpstan/baseline.php b/tests/phpstan/baseline.php index d656589f4a069..2ad8bac653169 100644 --- a/tests/phpstan/baseline.php +++ b/tests/phpstan/baseline.php @@ -49,36 +49,6 @@ 'count' => 1, 'path' => __DIR__ . '/../../src/wp-admin/themes.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Constant HEADER_IMAGE_HEIGHT not found\\.$#', - 'identifier' => 'constant.notFound', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/functions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', - 'identifier' => 'constant.notFound', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/functions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Constant HEADER_TEXTCOLOR not found\\.$#', - 'identifier' => 'constant.notFound', - 'count' => 2, - 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/functions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', - 'identifier' => 'constant.notFound', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/header.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', - 'identifier' => 'constant.notFound', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-content/themes/twentyeleven/showcase.php', -]; $ignoreErrors[] = [ 'message' => '#^Function twentyseventeen_edit_link invoked with 1 parameter, 0 required\\.$#', 'identifier' => 'arguments.count', @@ -97,24 +67,6 @@ 'count' => 1, 'path' => __DIR__ . '/../../src/wp-content/themes/twentyseventeen/template-parts/page/content-page.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Constant HEADER_IMAGE_HEIGHT not found\\.$#', - 'identifier' => 'constant.notFound', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-content/themes/twentyten/functions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', - 'identifier' => 'constant.notFound', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-content/themes/twentyten/functions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Constant HEADER_IMAGE_WIDTH not found\\.$#', - 'identifier' => 'constant.notFound', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-content/themes/twentyten/header.php', -]; $ignoreErrors[] = [ 'message' => '#^Function wp_cache_switch_to_blog_fallback invoked with 1 parameter, 0 required\\.$#', 'identifier' => 'arguments.count', diff --git a/tests/phpstan/bootstrap.php b/tests/phpstan/bootstrap.php index c87a26babf83d..77a597609270e 100644 --- a/tests/phpstan/bootstrap.php +++ b/tests/phpstan/bootstrap.php @@ -93,3 +93,12 @@ define( 'FS_TIMEOUT', 1 ); define( 'FS_CHMOD_DIR', 1 ); define( 'FS_CHMOD_FILE', 1 ); + +// Theme constants referenced in add_theme_support(). +define( 'NO_HEADER_TEXT', false ); +define( 'HEADER_IMAGE_WIDTH', 0 ); +define( 'HEADER_IMAGE_HEIGHT', 0 ); +define( 'HEADER_TEXTCOLOR', '' ); +define( 'HEADER_IMAGE', '' ); +define( 'BACKGROUND_COLOR', '' ); +define( 'BACKGROUND_IMAGE', '' ); From d39600aa5b0d650b6d49cb6ce23594e3dfd95772 Mon Sep 17 00:00:00 2001 From: Christoph Daum Date: Tue, 24 Feb 2026 09:18:58 +0100 Subject: [PATCH 08/15] Docs: Add `@return never` to `dead_db()`. --- src/wp-includes/functions.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 4b6330a697780..e4b96c6418c63 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5501,6 +5501,8 @@ function wp_ob_end_flush_all() { * @since 2.3.2 * * @global wpdb $wpdb WordPress database abstraction object. + * + * @return never */ function dead_db() { global $wpdb; From 75797b7afa805a425e77e2b4ac7e6fce3f200c4c Mon Sep 17 00:00:00 2001 From: Christoph Daum Date: Tue, 24 Feb 2026 10:42:28 +0100 Subject: [PATCH 09/15] fix(phpstan): Ignore return.never on dead_db() PHPStan cannot verify that wp_die() always terminates due to its conditional return type and treatPhpDocTypesAsCertain being disabled. --- src/wp-includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index e4b96c6418c63..101585166bd65 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5521,7 +5521,7 @@ function dead_db() { } // Otherwise, be terse. - wp_die( '

' . __( 'Error establishing a database connection' ) . '

', __( 'Database Error' ) ); + wp_die( '

' . __( 'Error establishing a database connection' ) . '

', __( 'Database Error' ) ); // @phpstan-ignore return.never (wp_die() always exits by default.) } /** From e55878c43fe22cdd2289b1480e9af195f002101d Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 24 Feb 2026 15:18:55 -0800 Subject: [PATCH 10/15] Fix phpstan-return syntax Co-authored-by: Christoph Daum --- src/wp-includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 101585166bd65..afc421079772a 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -3766,7 +3766,7 @@ function wp_nonce_ays( $action ) { * } * @return never|void Returns void if `$args['exit']` is false, otherwise exits. * - * @phpstan-return ( $args['exit'] is false ? void : never ) + * @phpstan-return ( $args is array{exit: false} ? void : never ) */ function wp_die( $message = '', $title = '', $args = array() ) { global $wp_query; From 46b656acb44e755085cb5e7d450b7b882e6a0eda Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 24 Feb 2026 15:19:03 -0800 Subject: [PATCH 11/15] Remove now-unnecessary phpstan-ignore --- src/wp-includes/functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index afc421079772a..8bf46ef0b871f 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5521,7 +5521,7 @@ function dead_db() { } // Otherwise, be terse. - wp_die( '

' . __( 'Error establishing a database connection' ) . '

', __( 'Database Error' ) ); // @phpstan-ignore return.never (wp_die() always exits by default.) + wp_die( '

' . __( 'Error establishing a database connection' ) . '

', __( 'Database Error' ) ); } /** From 3c46095d92b4321a091937681e4586f9e7f7f9eb Mon Sep 17 00:00:00 2001 From: Christoph Daum Date: Wed, 25 Feb 2026 08:14:38 +0100 Subject: [PATCH 12/15] docs: Refine phpdoc of dead_db() Co-authored-by: Weston Ruter --- src/wp-includes/class-wpdb.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index 23c865b87d817..de4f86ce753b0 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -2117,7 +2117,9 @@ public function parse_db_host( $host ) { * @since 3.9.0 * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return bool|void True if the connection is up. + * @return bool|never Whether the connection is up. + * + * @phpstan-return ( $allow_bail is true ? bool|never : bool ) */ public function check_connection( $allow_bail = true ) { // Check if the connection is alive. From c52438ac35ca5627d07b63fea65c6e5f008fc873 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 3 Mar 2026 19:28:22 -0800 Subject: [PATCH 13/15] Remove never from check_connection return --- src/wp-includes/class-wpdb.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wpdb.php b/src/wp-includes/class-wpdb.php index de4f86ce753b0..60026dbdc5c16 100644 --- a/src/wp-includes/class-wpdb.php +++ b/src/wp-includes/class-wpdb.php @@ -2117,7 +2117,7 @@ public function parse_db_host( $host ) { * @since 3.9.0 * * @param bool $allow_bail Optional. Allows the function to bail. Default true. - * @return bool|never Whether the connection is up. + * @return bool Whether the connection is up. Exits when `$allow_bail` is true and the connection is down. * * @phpstan-return ( $allow_bail is true ? bool|never : bool ) */ From 87a2c049b80664d5cfbf3b777b72a13059c49fff Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 3 Mar 2026 19:29:22 -0800 Subject: [PATCH 14/15] Remove errors from baseline which were fixed by never returns --- tests/phpstan/baseline.php | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/tests/phpstan/baseline.php b/tests/phpstan/baseline.php index 2ad8bac653169..0ebe3bbad7266 100644 --- a/tests/phpstan/baseline.php +++ b/tests/phpstan/baseline.php @@ -1,30 +1,6 @@ '#^Call to function compact\\(\\) contains possibly undefined variable \\$comment_author\\.$#', - 'identifier' => 'variable.undefined', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-admin/includes/ajax-actions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Call to function compact\\(\\) contains possibly undefined variable \\$comment_author_email\\.$#', - 'identifier' => 'variable.undefined', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-admin/includes/ajax-actions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Call to function compact\\(\\) contains possibly undefined variable \\$comment_author_url\\.$#', - 'identifier' => 'variable.undefined', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-admin/includes/ajax-actions.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Call to function compact\\(\\) contains possibly undefined variable \\$user_id\\.$#', - 'identifier' => 'variable.undefined', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-admin/includes/ajax-actions.php', -]; $ignoreErrors[] = [ 'message' => '#^Variable \\$_POST in isset\\(\\) always exists and is not nullable\\.$#', 'identifier' => 'isset.variable', From 95ddce21f75478d4b34e7873315e0de7b4c39885 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 3 Mar 2026 19:37:31 -0800 Subject: [PATCH 15/15] Resolve isset.variable error since $_POST global is always set --- src/wp-admin/includes/class-custom-image-header.php | 2 +- tests/phpstan/baseline.php | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/wp-admin/includes/class-custom-image-header.php b/src/wp-admin/includes/class-custom-image-header.php index eb65605728062..2c0eb26c0fc9a 100644 --- a/src/wp-admin/includes/class-custom-image-header.php +++ b/src/wp-admin/includes/class-custom-image-header.php @@ -841,7 +841,7 @@ public function step_2() { $file = get_attached_file( $attachment_id, true ); $url = wp_get_attachment_image_src( $attachment_id, 'full' ); $url = $url[0]; - } elseif ( isset( $_POST ) ) { + } else { $data = $this->step_2_manage_upload(); $attachment_id = $data['attachment_id']; $file = $data['file']; diff --git a/tests/phpstan/baseline.php b/tests/phpstan/baseline.php index 0ebe3bbad7266..810d719f57b6a 100644 --- a/tests/phpstan/baseline.php +++ b/tests/phpstan/baseline.php @@ -1,12 +1,6 @@ '#^Variable \\$_POST in isset\\(\\) always exists and is not nullable\\.$#', - 'identifier' => 'isset.variable', - 'count' => 1, - 'path' => __DIR__ . '/../../src/wp-admin/includes/class-custom-image-header.php', -]; $ignoreErrors[] = [ 'message' => '#^Variable \\$class in empty\\(\\) always exists and is always falsy\\.$#', 'identifier' => 'empty.variable',