Skip to content

Docs: Narrow deprecated parameters to their default values in PHPStan types - #13889

Closed
swissspidy wants to merge 8 commits into
WordPress:trunkfrom
swissspidy:fix/phpstan-deprecated-params
Closed

swissspidy wants to merge 8 commits into
WordPress:trunkfrom
swissspidy:fix/phpstan-deprecated-params

Conversation

@swissspidy

@swissspidy swissspidy commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Split out of #13530, as proposed in this comment (subset 2).

This adds @phpstan-param tags that narrow unused, deprecated parameters to the literal value of their default: '', null, false, true, array{} or '–'. Static analysis then flags any caller that passes something else. The types come from the function map in php-stubs/wordpress-stubs. 38 functions are covered.

Depends on #13872. This branch is built on top of that PR, because the types added here for wp_upload_bits(), add_option(), iframe_header() and wp_install() flag the calls that PR fixes. Until #13872 lands, its commits also appear in this diff; the only new commit here is the last one.

Changes from #13530

  • Left out redirect_this_site(). It is hooked on allowed_redirect_hosts, which passes it an array.
  • Left out WP_Widget::update_callback(). Core registers it with array( 'number' => -1 ).
  • Left out wp_count_terms(). Its legacy argument form still passes the args through $deprecated.
  • wp_get_typography_font_size_value() narrows $settings to array, since the boolean form was deprecated in 6.6.0.
  • unregister_setting() is in Docs: Add PHPStan types for optional callback parameters #13890 instead, because its $deprecated is the last entry in the parameter.defaultValue baseline that PR removes.

Effect on the analysis

composer run phpstan passes with no baseline changes. At level 10 the change introduces no new errors and fixes 3.

Trac ticket: https://core.trac.wordpress.org/ticket/65817

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5.5
Used for: Splitting #13530 by tag kind, applying the corrections from the review analysis on #13530, checking each subset with composer run phpstan (also at level 10, compared against trunk) and phpcs, and drafting the commit message and this description. Reviewed by me.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VieGtSQtUoVfHiGwTmkvtc

westonruter and others added 6 commits September 30, 2026 13:44
The `$deprecated` parameter of `wp_upload_bits()` is documented as "Not used. Set to null." `wp_generate_attachment_metadata()` passed an empty string instead when uploading the cover art embedded in audio and video files. The value is ignored either way, so this changes no behavior; it brings the call in line with the documented type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `$deprecated` parameter of `add_option()` is documented as a string, defaulting to an empty string. `upgrade_340()` passed null when re-adding the `uninstall_plugins` option without autoloading. `add_option()` only warns when the argument is non-empty, so this changes no behavior; it brings the call in line with the documented type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second parameter of `iframe_header()` was renamed to `$deprecated` in WordPress 4.2 and has not been used since. The plugin reactivation screen in `wp-admin/update.php` still passed `true` for it. Dropping the argument changes no behavior.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ests

The `$deprecated` parameter of `wp_install()` is documented as a string, defaulting to an empty string, which is also what `wp-admin/install.php` passes. The PHPUnit install bootstrap passed null instead. `wp_install()` only warns when the argument is non-empty, so this changes no behavior; it brings the call in line with the documented type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… types.

Adds `@phpstan-param` tags that narrow unused, deprecated parameters to the literal value of their default (`''`, `null`, `false`, `true`, `array{}` or `'&WordPress#8211;'`), so that static analysis flags a caller passing anything else. These types come from the function map in php-stubs/wordpress-stubs.

`wp_get_typography_font_size_value()` also narrows `$settings` to `array`, since its boolean form was deprecated in 6.6.0.

Three entries from the map are left out because core uses the parameter: `redirect_this_site()` is hooked to `allowed_redirect_hosts` and receives an array, `WP_Widget::update_callback()` is registered with `array( 'number' => -1 )`, and `wp_count_terms()` still accepts the legacy argument form through `$deprecated`.

This builds on the call-site fixes that pass the documented values to `wp_upload_bits()`, `add_option()`, `iframe_header()` and `wp_install()`.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VieGtSQtUoVfHiGwTmkvtc
Copilot AI balanced review requested due to automatic review settings October 1, 2026 09:00
@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props westonruter, swissspidy.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The annotations and no-op call-site corrections are sound, with only a non-blocking docblock-order consistency issue.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
What changed in this PR

Narrows deprecated parameters to their supported default values for PHPStan, allowing static analysis to detect obsolete argument usage.

Changes:

  • Adds literal PHPStan parameter types across 38 functions.
  • Narrows typography settings to arrays.
  • Normalizes four call sites and removes the resolved baseline entry.
File Description
tests/​phpunit/​includes/​install.php Passes the documented wp_install() value.
tests/​phpstan/​baselines/​argument.type.neon Removes the resolved add_option() error.
src/​wp-includes/​widgets.php Narrows the deprecated sidebar argument.
src/​wp-includes/​user.php Narrows the deprecated user-option argument.
src/​wp-includes/​revision.php Narrows the revision argument.
src/​wp-includes/​post-template.php Narrows the attachment-link argument.
src/​wp-includes/​option.php Narrows deprecated option arguments.
src/​wp-includes/​ms-functions.php Narrows multisite notification/count arguments.
src/​wp-includes/​ms-blogs.php Narrows deprecated blog arguments.
src/​wp-includes/​meta.php Narrows the legacy meta callback argument.
src/​wp-includes/​link-template.php Narrows the delete-link argument.
src/​wp-includes/​l10n.php Narrows the legacy textdomain path.
src/​wp-includes/​kses.php Narrows the SafeCSS argument.
src/​wp-includes/​functions.php Narrows HTTP and upload arguments.
src/​wp-includes/​formatting.php Narrows deprecated formatting arguments.
src/​wp-includes/​feed.php Narrows legacy feed separators.
src/​wp-includes/​comment.php Narrows the pingback argument.
src/​wp-includes/​comment-template.php Narrows deprecated comment arguments.
src/​wp-includes/​class-wp-theme-json-resolver.php Requires empty legacy theme data.
src/​wp-includes/​class-wp-object-cache.php Narrows the cache deletion argument.
src/​wp-includes/​category-template.php Requires an empty legacy visited list.
src/​wp-includes/​block-template-utils.php Narrows the legacy request argument.
src/​wp-includes/​block-supports/​typography.php Restricts settings to arrays.
src/​wp-includes/​block-patterns.php Narrows the legacy screen argument.
src/​wp-includes/​author-template.php Narrows deprecated author arguments.
src/​wp-admin/​update.php Removes an obsolete iframe argument.
src/​wp-admin/​includes/​upgrade.php Types install arguments and fixes a caller.
src/​wp-admin/​includes/​template.php Narrows the iframe argument.
src/​wp-admin/​includes/​plugin.php Narrows the plugin deletion argument.
src/​wp-admin/​includes/​plugin-install.php Narrows the search-form argument.
src/​wp-admin/​includes/​meta-boxes.php Narrows the XFN argument.
src/​wp-admin/​includes/​image.php Passes null to wp_upload_bits().

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/wp-includes/functions.php Outdated

Copy link
Copy Markdown
Member Author

🤖 Comment by Claude Opus 5.5

Props for this subset, gathered from the full history of functionMap.php in php-stubs/wordpress-stubs. A change counts only where it introduced or changed the specific tag this PR carries, not just any change to the function's map entry. Purely mechanical changes are left out: tag key renames (php-stubs/wordpress-stubs#420), parameter renames (php-stubs/wordpress-stubs#115), coding standards (php-stubs/wordpress-stubs#119) and the duplicate-code refactor (php-stubs/wordpress-stubs#85).

Stubs change Author Entries
php-stubs/wordpress-stubs#433 @IanDelMar wp_get_typography_font_size_value()
php-stubs/wordpress-stubs#436 @IanDelMar _load_remote_block_patterns(), _wp_post_revision_fields(), add_option(), comments_link(), convert_chars(), delete_plugins(), discover_pingback_server_uri(), get_category_parents(), get_delete_post_link(), get_last_updated(), get_site_option(), get_the_author(), get_user_option(), get_wp_title_rss(), iframe_header(), inject_ignored_hooked_blocks_metadata_attributes(), install_search_form(), is_email(), load_plugin_textdomain(), newblog_notify_siteadmin(), register_meta(), safecss_filter_attr(), switch_to_blog(), the_attachment_link(), the_author(), the_author_posts_link(), trackback_rdf(), update_blog_option(), update_posts_count(), wp_get_http_headers(), wp_get_sidebars_widgets(), wp_install(), WP_Object_Cache::delete(), WP_Theme_JSON_Resolver::get_theme_data(), wp_title_rss(), wp_upload_bits(), xfn_check()

Props for this PR (swissspidy for the split, westonruter for the review that shaped it):

swissspidy, westonruter, marian1

Generated by Claude Code

@westonruter

westonruter commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

I tried merging in the latest from trunk (to pull in #13872 / r64045 / 441b562) but I'm unable to push. It seems the PR is not enabling maintainers to push.

@westonruter westonruter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Comment by Claude Opus 5.5

Each added @phpstan-param was checked against its parameter's default value in the signature. All 37 match, with one deliberate exception noted below:

  • '': xfn_check(), delete_plugins(), wp_install(), get_the_author(), the_author(), the_author_posts_link(), comments_link() (both), trackback_rdf(), discover_pingback_server_uri(), convert_chars(), safecss_filter_attr(), get_delete_post_link(), get_last_updated(), newblog_notify_siteadmin(), update_posts_count(), add_option(), get_user_option()
  • '&#8211;': get_wp_title_rss(), wp_title_rss()
  • true: install_search_form(), the_author()'s $deprecated_echo, get_site_option(), wp_get_sidebars_widgets()
  • false: iframe_header(), WP_Object_Cache::delete(), is_email(), wp_get_http_headers(), load_plugin_textdomain(), the_attachment_link(), _wp_post_revision_fields()
  • null: _load_remote_block_patterns(), inject_ignored_hooked_blocks_metadata_attributes(), register_meta(), update_blog_option(), switch_to_blog(), and wp_upload_bits() (no default, but documented as "Set to null")
  • array{}: get_category_parents(), WP_Theme_JSON_Resolver::get_theme_data()

The hooked callbacks do not receive the deprecated argument: convert_chars() and inject_ignored_hooked_blocks_metadata_attributes() use the default accepted_args of 1, and newblog_notify_siteadmin() is registered with 1 explicitly.

Findings

  1. validate_email() contradicts the new is_email() type. In src/wp-includes/ms-deprecated.php it calls is_email( $email, $check_domain ), where $check_domain is a bool defaulting to true, which violates @phpstan-param false $deprecated. CI passes only because tests/phpstan/base.neon excludes the *deprecated.php files from analysis. Dropping the argument fixes it, and also removes a redundant notice: a default call currently fires _deprecated_function() for validate_email() and then _deprecated_argument() from inside is_email().

  2. wp_get_typography_font_size_value() is the one tag that isn't the default value, and that's intended. It is narrowed to array rather than array{}, since only the boolean form of $settings was deprecated in 6.6.0. The plain @param description is out of date, though: it still says "Default is false", while the default has been array() since that change.

  3. Nit: in wp_upload_bits() the new @phpstan-param null $deprecated is placed after the @phpstan-return block. Elsewhere in this PR (for example delete_plugins()), @phpstan-param comes before @phpstan-return.

Since maintainer edits are not enabled on this PR, here is a diff for the first two findings:

diff --git a/src/wp-includes/block-supports/typography.php b/src/wp-includes/block-supports/typography.php
index 9ecc1b6edd..609ff300ba 100644
--- a/src/wp-includes/block-supports/typography.php
+++ b/src/wp-includes/block-supports/typography.php
@@ -557,8 +557,8 @@ function wp_get_computed_fluid_typography_value( $args = array() ) {
  *     @type string           $slug Kebab-case, unique identifier for the font size preset.
  *     @type string|int|float $size CSS font-size value, including units if applicable.
  * }
- * @param bool|array $settings Optional Theme JSON settings array that overrides any global theme settings.
- *                             Default is false.
+ * @param bool|array $settings Optional. Theme JSON settings array that overrides any global theme settings.
+ *                             Passing a boolean is deprecated. Default empty array.
  * @return string|null Font-size value or null if a size is not passed in $preset.
  *
  * @phpstan-param array $settings
diff --git a/src/wp-includes/ms-deprecated.php b/src/wp-includes/ms-deprecated.php
index c1de27db4c..8b4a1ff6f0 100644
--- a/src/wp-includes/ms-deprecated.php
+++ b/src/wp-includes/ms-deprecated.php
@@ -171,7 +171,7 @@ function is_main_blog() {
  */
 function validate_email( $email, $check_domain = true) {
 	_deprecated_function( __FUNCTION__, '3.0.0', 'is_email()' );
-	return is_email( $email, $check_domain );
+	return is_email( $email );
 }
 
 /**

@westonruter westonruter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swissspidy and others added 2 commits October 5, 2026 13:44
Stop passing the deprecated $check_domain argument from validate_email() to is_email(), update the $settings description of wp_get_typography_font_size_value(), and place @phpstan-param before @phpstan-return in wp_upload_bits().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015BuoHZQvJMvPEYp4Sfjgvd
@swissspidy
swissspidy requested a review from westonruter October 5, 2026 13:49
@swissspidy

Copy link
Copy Markdown
Member Author

It seems the PR is not enabling maintainers to push.

Ugh, no idea why this wasn't enabled by default on all my PRs. Fixed now.

Appreciate your review & patch!

wporg-sync pushed a commit that referenced this pull request Oct 6, 2026
This adds `@phpstan-param` tags that narrow unused, deprecated parameters to the literal value of their default, so that static analysis flags callers which still pass something else. The types come from php-stubs/wordpress-stubs. `wp_get_typography_font_size_value()` narrows `$settings` to `array`, since passing a boolean was deprecated in 6.6.0.

`validate_email()` also stops passing its `$check_domain` argument to `is_email()`, where it is deprecated and triggered a second deprecation notice.

Developed in: #13889

Follow-up to r64045.

Props marian1, swissspidy, westonruter.
See #65817.

git-svn-id: https://develop.svn.wordpress.org/trunk@64163 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 6, 2026
This adds `@phpstan-param` tags that narrow unused, deprecated parameters to the literal value of their default, so that static analysis flags callers which still pass something else. The types come from php-stubs/wordpress-stubs. `wp_get_typography_font_size_value()` narrows `$settings` to `array`, since passing a boolean was deprecated in 6.6.0.

`validate_email()` also stops passing its `$check_domain` argument to `is_email()`, where it is deprecated and triggered a second deprecation notice.

Developed in: WordPress/wordpress-develop#13889

Follow-up to r64045.

Props marian1, swissspidy, westonruter.
See #65817.
Built from https://develop.svn.wordpress.org/trunk@64163


git-svn-id: http://core.svn.wordpress.org/trunk@63314 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@swissspidy

Copy link
Copy Markdown
Member Author

@swissspidy swissspidy closed this Oct 6, 2026
@swissspidy
swissspidy deleted the fix/phpstan-deprecated-params branch October 8, 2026 07:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants