Repository navigation
Docs: Narrow deprecated parameters to their default values in PHPStan types - #13889
swissspidy wants to merge 8 commits into
Conversation
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
|
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 Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe 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
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
There was a problem hiding this comment.
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
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 by Claude Opus 5.5 Props for this subset, gathered from the full history of
Props for this PR (swissspidy for the split, westonruter for the review that shaped it): Generated by Claude Code |
westonruter
left a comment
There was a problem hiding this comment.
🤖 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()'–':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(), andwp_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
-
validate_email()contradicts the newis_email()type. Insrc/wp-includes/ms-deprecated.phpit callsis_email( $email, $check_domain ), where$check_domainis abooldefaulting totrue, which violates@phpstan-param false $deprecated. CI passes only becausetests/phpstan/base.neonexcludes the*deprecated.phpfiles from analysis. Dropping the argument fixes it, and also removes a redundant notice: a default call currently fires_deprecated_function()forvalidate_email()and then_deprecated_argument()from insideis_email(). -
wp_get_typography_font_size_value()is the one tag that isn't the default value, and that's intended. It is narrowed toarrayrather thanarray{}, since only the boolean form of$settingswas deprecated in 6.6.0. The plain@paramdescription is out of date, though: it still says "Default is false", while the default has beenarray()since that change. -
Nit: in
wp_upload_bits()the new@phpstan-param null $deprecatedis placed after the@phpstan-returnblock. Elsewhere in this PR (for exampledelete_plugins()),@phpstan-paramcomes 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 );
}
/**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
Ugh, no idea why this wasn't enabled by default on all my PRs. Fixed now. Appreciate your review & patch! |
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
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

Split out of #13530, as proposed in this comment (subset 2).
This adds
@phpstan-paramtags 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()andwp_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
redirect_this_site(). It is hooked onallowed_redirect_hosts, which passes it an array.WP_Widget::update_callback(). Core registers it witharray( 'number' => -1 ).wp_count_terms(). Its legacy argument form still passes the args through$deprecated.wp_get_typography_font_size_value()narrows$settingstoarray, 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$deprecatedis the last entry in theparameter.defaultValuebaseline that PR removes.Effect on the analysis
composer run phpstanpasses 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) andphpcs, 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