Skip to content

Code Quality: Fix the return.unusedType PHPStan errors and remove the baseline - #15387

Open
mukeshpanchal27 wants to merge 17 commits into
WordPress:trunkfrom
mukeshpanchal27:fix/validate-another-blog-signup-return-type
Open

mukeshpanchal27 wants to merge 17 commits into
WordPress:trunkfrom
mukeshpanchal27:fix/validate-another-blog-signup-return-type

Conversation

@mukeshpanchal27

@mukeshpanchal27 mukeshpanchal27 commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

This PR fixes every return.unusedType error that PHPStan reports, and deletes tests/phpstan/baselines/return.unusedType.neon. Each function has its own commit. There is no runtime change.

PHPStan reads the return type of apply_filters() from the @param tag of the filter. Several errors came from a filter @param tag that listed too few types. In those cases the function's @return tag was correct, so this PR fixes the filter docs instead.

Wrong type removed from @return

Function Change Reason
validate_another_blog_signup() Removed null It returns true or false, or calls die().
_fix_attachment_links() Removed WP_Error It calls wp_update_post() without $wp_error, so a failure returns 0.
get_preferred_from_update_core() Removed array It returns an update object or false.
WP_Recovery_Mode_Cookie_Service::recovery_mode_hash() Removed false hash_hmac() with sha1 cannot fail.
_set_preview() Removed false It always returns the post it receives.
get_term_to_edit() Now WP_Term|string|WP_Error It never returns int or null, and the old tag did not list the term object.

The get_preferred_from_update_core() change also clears three property.nonObject errors in WP_Automatic_Updater. This PR removes those three entries from the property.nonObject baseline.

Filter @param tag corrected

Filter Change Reason
plugins_api_result Added array plugins_api() documents an array for hot_tags.
the_tags Now string|false|WP_Error This matches get_the_term_list().
wp_code_editor_settings Added false The filter description says a falsey value disables the editor.
get_post_gallery Now string|array|false reset() returns false when the post has no gallery. The function @return now matches.
wp_mime_type_icon Added false $icon stays false when no icon matches.
allow_password_reset Added WP_Error retrieve_password() already handles a WP_Error result.

Other changes

  • _make_cat_compat() now accepts null. get_category() passes it the result of get_term() by reference, and PHPStan assumed that result could not be null after the call.
  • wp_imagecreatetruecolor() keeps GdImage in its return type. PHPStan analyses against PHP 7.4, where imagecreatetruecolor() returns a resource. On PHP 8 it returns GdImage. This PR moves the entry to the permanent ignore list in phpstan.neon.dist and explains why there, the same way the substr_compare() entry does.

Testing

  • composer phpstan reports no errors.
  • php -l passes on every changed file.
  • PHPCS reports the same warnings on the changed files before and after this PR.

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: Finding the fixes, editing the docblocks and baselines, and drafting the PR. I reviewed the changes.


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

…urn type.

The function returns `true` or `false`. When the user is not logged in, it calls `die()` and does not return. Removing `null` from the `@return` tag removes the `return.unusedType` entry from the PHPStan baseline. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mukeshpanchal27 mukeshpanchal27 self-assigned this Nov 3, 2026
@github-actions

github-actions Bot commented Nov 3, 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.

@mukeshpanchal27
mukeshpanchal27 marked this pull request as ready for review November 3, 2026 04:45
@github-actions

github-actions Bot commented Nov 3, 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.

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

Props mukesh27, westonruter.

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


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

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.

🟢 Approval recommended

The documentation and PHPStan baseline now consistently describe the function’s boolean-only return behavior, with no runtime changes or active review issues indicated.

No open issues 🎉

What changed in this PR

Updates validate_another_blog_signup() documentation and its PHPStan baseline to reflect that the function returns only a boolean when it returns. There is no runtime behavior change.

Changes:

  • Removes null from the function’s documented return type.
  • Removes the obsolete PHPStan return.unusedType baseline entry.
File Description
tests/​phpstan/​baselines/​return.unusedType.neon Removes the obsolete PHPStan baseline entry.
src/​wp-signup.php Updates the return documentation to bool.

Review effort: Lite

@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.

Can you fix the other return.unusedType errors as well so the baseline file can be removed?

mukeshpanchal27 and others added 15 commits November 4, 2026 13:09
`plugins_api()` documents that it returns an array for the `hot_tags` action, and the docblock says the `plugins_api_result` filter can change the response object or array. The filter's `@param` tag listed only `object|WP_Error`, so PHPStan concluded that the function never returns an array. This change adds `array` to the filter's `@param` tag and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

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

The function calls `wp_update_post()` without the `$wp_error` argument, so an update failure returns `0` and never a `WP_Error`. This change removes `WP_Error` from the `@return` tag and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

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

The function returns the first update object from `get_core_updates()`, a placeholder object when there are no updates, or `false`. It never returns an array. This change removes `array` from the `@return` tag and removes the matching `return.unusedType` baseline entry.

`WP_Automatic_Updater` reads properties from the result of this function. Before this change, PHPStan reported three `property.nonObject` errors there because the result could be an array. This change also removes those three baseline entries. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`get_the_tag_list()` passes the result of `get_the_term_list()` to the `the_tags` filter. That result is a string, `false` when there are no terms, or a `WP_Error` on failure. The filter's `@param` tag listed only `string`, so PHPStan concluded that the function never returns `false` or `WP_Error`. This change documents all three types on the filter and removes the two matching `return.unusedType` baseline entries. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`get_category()` passes the result of `get_term()` to `_make_cat_compat()` by reference. That result is `null` when the category does not exist, and `_make_cat_compat()` leaves `null` unchanged. The parameter type did not include `null`, so PHPStan assumed that the variable could not be `null` after the call. It then reported that `get_category()` never returns `null`. This change adds `null` to the parameter type and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`WP_Recovery_Mode_Cookie_Service::recovery_mode_hash()` returns the result of `hash_hmac()` with the `sha1` algorithm. `hash_hmac()` returns `false` only for an unknown algorithm, and `sha1` is always available. This change removes `false` from the `@return` tag and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `wp_code_editor_settings` filter description says that a falsey value disables the code editor, and `wp_enqueue_code_editor()` checks for it. The filter's `@param` tag listed only `array`, so PHPStan concluded that `wp_get_code_editor_settings()` never returns `false`. This change adds `false` to the filter's `@param` tag and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`get_post_gallery()` returns the first item of `get_post_galleries()`. That item is an HTML string when `$html` is true, and an array otherwise. When the post has no gallery, `reset()` returns `false`. The `get_post_gallery` filter's `@param` tag listed only `array`, so PHPStan concluded that the function never returns a string. This change documents `string|array|false` on the filter and on the function, and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`wp_mime_type_icon()` first reads the icon from the object cache, and `wp_cache_get()` returns `false` on a miss. If no icon file matches the MIME type, `$icon` stays `false` and the function passes it to the `wp_mime_type_icon` filter. The filter's `@param` tag listed only `string`, so PHPStan concluded that the function never returns `false`. This change adds `false` to the filter's `@param` tag and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`_set_preview()` returns the post object that it receives, with the autosave content applied when one exists. It has no path that returns `false`. This change removes `false` from the `@return` tag and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`get_term_to_edit()` returns the `WP_Error` from `get_term()`, an empty string when the term does not exist, or the term object from `sanitize_term()`. It never returns an integer or `null`, and the `@return` tag did not list the term object. This change documents `WP_Term|string|WP_Error` and removes the two matching `return.unusedType` baseline entries. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`retrieve_password()` checks whether `wp_is_password_reset_allowed_for_user()` returns a `WP_Error` and passes it on, so a filter callback can return a `WP_Error` to explain why a reset is not allowed. The filter's `@param` tag listed only `bool`, so PHPStan concluded that the function never returns a `WP_Error`. This change adds `WP_Error` to the filter's `@param` tag and removes the matching `return.unusedType` baseline entry. There is no runtime change.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The earlier commits fixed every other entry in this baseline. The last entry reports that `wp_imagecreatetruecolor()` never returns `GdImage`. That report is a false positive. `imagecreatetruecolor()` returns a resource on PHP 7.4 and a `GdImage` instance on PHP 8.0+. PHPStan uses its pre-8.0 function map because `phpVersion.min` is 70400, so it sees only the resource.

This change moves that entry to the permanent ignore list in `phpstan.neon.dist` with an explanation, deletes the baseline file, and removes its `includes` line.

See #65817.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mukeshpanchal27 mukeshpanchal27 changed the title Code Quality: Remove null from validate_another_blog_signup() return type Code Quality: Fix the return.unusedType PHPStan errors and remove the baseline Nov 4, 2026
The continuation lines in the `get_term_to_edit()` `@return` tag and the `allow_password_reset` filter `@param` tag started one column too early. This change aligns them with the description text above.

See #65817.

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

Copy link
Copy Markdown
Member Author

@westonruter Done. This PR now fixes every return.unusedType error and deletes tests/phpstan/baselines/return.unusedType.neon, along with its includes line. Each function has its own commit, and composer phpstan reports no errors.

Many of the errors came from filter docs, not from the functions. The PHPStan extension takes the return type of apply_filters() from the filter's @param tag. In those cases the function's @return tag was correct, so I added the missing types to the filter instead. This applies to plugins_api_result, the_tags, wp_code_editor_settings, get_post_gallery, wp_mime_type_icon and allow_password_reset.

The get_preferred_from_update_core() fix also cleared three property.nonObject errors in WP_Automatic_Updater, so I removed those baseline entries too.

One entry needs your opinion. PHPStan reports that wp_imagecreatetruecolor() never returns GdImage, but I think this report is a false positive. PHPStan analyses against PHP 7.4, where imagecreatetruecolor() returns a resource. On PHP 8 it returns GdImage. Removing GdImage would make the docblock wrong on PHP 8. I moved the entry to the permanent ignore list in phpstan.neon.dist, with a comment that explains why, like the substr_compare() entry. If you prefer another approach, I can change it.

The PR description lists every change.

@mukeshpanchal27
mukeshpanchal27 requested review from westonruter and a lite review from Copilot November 4, 2026 08:08

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.

🟢 Approval recommended

No active review issues remain, with the supplied evidence indicating the PHPStan documentation and baseline corrections are complete while preserving the GD cross-version exception.

No open issues 🎉

Review effort: Lite

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