Skip to content

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

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

mukeshpanchal27 wants to merge 37 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

✅ Committed in r65410 (dd5ce8e).


This PR fixes every return.unusedType error that PHPStan reports, and deletes tests/phpstan/baselines/return.unusedType.neon. While fixing those errors, it also tightens related types that were wrong or too loose, and fixes a bug in wp_mime_type_icon() that the fixes uncovered.

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.

Runtime changes

  • wp_mime_type_icon(): when an attachment ID (or 0) was passed and no icon matched, $icon was never assigned, so the wp_mime_type_icon filter received null along with an "Undefined variable $icon" warning. $icon now starts as false, so the filter and the return value are string|false on every path. Cached values (both the mime_type_icon_{$mime} entry and the icon_files list) are only used when they are strings.
  • _set_preview(): the is_object() guard is removed. This function is core's the_preview callback, and WP_Query only applies that filter to a post already converted with get_post(), so the guard was unreachable. A survey of the plugin directory found no the_preview callback that returns a non-object, and no direct caller that passes one.

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, with @phpstan-return WP_Term|''|WP_Error It never returns int or null, the old tag did not list the term object, and the empty string is the only string it returns.

The get_preferred_from_update_core() change also clears three property.nonObject errors in WP_Automatic_Updater. This PR removes those 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<mixed>|false reset() returns false when the post has no gallery.
wp_mime_type_icon $icon is string|false, $mime is string|int $icon is false when no icon matches, and is a URL rather than a path. $mime and $post_id are 0 when no post is found for the passed ID.
allow_password_reset Added WP_Error retrieve_password() already handles a WP_Error result.

Types tightened

  • get_post_gallery(): conditional @phpstan-return so that $html = false gives the gallery data array and the default gives an HTML string. This clears echo type errors in the Twenty Thirteen and Twenty Seventeen gallery templates.
  • sanitize_term(): $term is array<string, mixed>|object, and a conditional @phpstan-return returns the same kind of value it was given (WP_Term, array, or object). This clears the get_term_to_edit() return type error and several offset-access errors on its result.
  • sanitize_term_field(): $value is string|int, since the integer fields are cast to int.
  • wp_match_mime_types(): returns array<array-key, string[]> rather than a bare array, which removes mixed foreach and offset errors in wp_mime_type_icon() and media_upload_library_form().

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.
  • New PHPUnit tests in Tests_Post_Attachments cover wp_mime_type_icon() when no icon matches (for an attachment ID and for a MIME type) and when the icon cache holds a non-string value. Both fail on the previous code. Run them with npm run test:php -- --filter test_wp_mime_type_icon.
  • 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, writing the tests, surveying plugin usage of the_preview, 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.

…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
westonruter and others added 4 commits November 11, 2026 09:35
Mirror sanitize_post() so that sanitize_term() returns the same type it
was given: a WP_Term stays a WP_Term, an array stays an array, and any
other object stays an object. Previously the return was array|object
regardless of input, so get_term_to_edit() was reported as returning
array|object instead of its documented WP_Term|string|WP_Error.

Also narrow get_term_to_edit() with `@phpstan-return WP_Term|''|WP_Error`,
since an empty string is the only string it returns, and note that a
WP_Error is also returned when the term ID is empty.

This removes 16 PHPStan errors across taxonomy.php, class-wp-term.php,
and class-wp-terms-list-table.php without adding any.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
Add `@phpstan-param object|array<string, mixed> $term` and return
`array<string, mixed>` for the array case, since the function reads and
writes term fields by name. This documents what sanitize_term() actually
requires.

Callers that pass loosely typed arrays (sanitize_category(), wp_insert_term(),
and wp_update_term()) are now
flagged with argument.type errors; their own array types should be
narrowed to match in a follow-up.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
The function casts the integer fields (term_id, parent, count,
term_group, term_taxonomy_id, and object_id) to int before anything
else, and WP_Term holds those fields as ints, so `$value` is
`string|int` rather than just `string`. Widen the `@param` and the
`T` template bound to match.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
Comment thread src/wp-includes/revision.php Resolved
* @param array $settings The array of settings passed to the code editor.
* A falsey value disables the editor.
* @param array $args {
* @param array|false $settings The array of settings passed to the code editor.

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.

Good. This matches the return value for wp_get_code_editor_settings():

@return array|false Settings for the code editor.

Comment thread src/wp-includes/post.php Resolved
westonruter and others added 6 commits November 11, 2026 11:42
When wp_mime_type_icon() was given an attachment ID (or 0) and no icon
matched, `$icon` was never assigned, so the filter received null along
with an "Undefined variable $icon" warning. For a MIME type string, the
value came straight from wp_cache_get(), which is untyped.

Initialize `$icon` to false, and only use the cached value when it is a
string, so the filter and the return value are always string|false.

Also correct the hook docs: `$icon` is a URL, not a path, and `$mime`
is 0 when the attachment does not exist. Add a test covering both the
attachment ID and MIME type paths when no icon matches.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
The function returns an array keyed by wildcard MIME type, each holding
the list of real MIME types it matched. Declaring it as plain `array`
left callers iterating over `mixed`, so wp_mime_type_icon() and
media_upload_library_form() reported foreach and array key type errors.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
The `icon_files` list can come from wp_cache_get(), so its values are
untyped, and `$icon` reached the wp_mime_type_icon filter as `mixed`.
Skip any matched entry that is not a string, so the filter and the
return value are string|false on every path.

Read the entry once through a local variable rather than checking and
then reading `$types[ $wild ]` again.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
_set_preview() is the core callback for the the_preview filter, which
WP_Query applies to `$this->posts[0]` after the posts have already been
converted with get_post(), so it always receives a WP_Post. With
`@param WP_Post`, the guard's body was unreachable (PHPStan typed
`$post` there as never) and contradicted the narrowed `@return WP_Post`.

A survey of plugins in the WordPress.org directory found no
the_preview callback that returns a non-object, and the plugins that
call _set_preview() directly only pass it post objects.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
get_post( 0 ) falls back to the global `$post`, so if an earlier test
left it set, the "nonexistent attachment ID" case would resolve a real
post and never reach the branch where `$mime` becomes 0. Pass
PHP_INT_MAX instead, which can never match an attachment.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
The returned array is keyed by the wildcard MIME types, and PHP casts
all-digit string keys to integers, so a wildcard such as an icon named
`404.png` produces an int key. Use `array-key` rather than `string` for
the key type. The values remain lists of matched MIME type strings.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
@github-actions

This comment has been minimized.

westonruter and others added 8 commits November 11, 2026 13:02
The wp_mime_type_icon filter docs already say `$mime` is 0 when an
attachment ID is passed for a nonexistent attachment. `$post_id` is also
0 in that case, not only when a MIME type is passed, so say so.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
`array<string, mixed>|object` is a plain generic rather than an array
shape, so it belongs in the published `@param` tag instead of a separate
`@phpstan-param` that duplicated it. PHPStan results are unchanged.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
get_post_gallery() returns gallery HTML when `$html` is true and an
array of gallery data when it is false, but its return type was the
union of both. Add a conditional `@phpstan-return` so callers that pass
`$html = false` (such as get_post_gallery_images()) get an array, and
callers using the default get a string, which clears the echo type
errors in the Twenty Thirteen and Twenty Seventeen gallery templates.

Type the get_post_gallery filter's array as `array<string, mixed>` to
match.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
In data mode, each gallery is built from shortcode_parse_atts(), which
puts positional shortcode attributes under integer keys, so
`[gallery foo ids="1,2"]` yields `0 => 'foo'` alongside the named
attributes. Type the gallery array as `array<mixed>` instead of
`array<string, mixed>`, in both the conditional return type and the
get_post_gallery filter.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
Cover the `is_string()` check on the `mime_type_icon_{$mime}` cache
read: when the cache holds true, an array, or an int, the icon must be
looked up again rather than returned as-is. Reverting to the unchecked
cache read makes all three cases fail.

Also add the `@ticket` annotation to the existing no-matching-icon test.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
The `$taxonomy` and `$context` lines, and the continuation lines below
them, were one column short of the `$term` line after its type was
widened to `array<string, mixed>|object`.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
wp_mime_type_icon() resolves a numeric `$mime` with get_post(), so 0
(the default) falls back to the global post. `$mime` and `$post_id` are
therefore 0 when no post is found for the passed ID, not specifically
when an attachment ID is nonexistent.

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c

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 review identifies no active issues, with the reported PHPStan findings resolved through aligned annotations, baseline cleanup, and targeted regression coverage.

No open issues 🎉

Review effort: Lite

westonruter and others added 2 commits November 11, 2026 19:38
A single-parameter array generic already has `array-key` keys, so
`array<array-key, string[]>` is the same type written longer. This
matches `array<mixed>` used for get_post_gallery().

Co-Authored-By: Claude Opus 5.5 (medium effort) <noreply@anthropic.com>
Claude-Code-Session-Id: 9a95e289-8165-4c03-a202-98d54206ca8c
wporg-sync pushed a commit that referenced this pull request Nov 12, 2026
Every `return.unusedType` error is fixed and its baseline removed. Most came from a `@return` tag that listed a type the function never returns. Others came from a filter `@param` tag that listed too few types: PHPStan derives the result of `apply_filters()` from the hook's first `@param`, so where the function's documented return was already right, the hook docs were corrected instead of loosening the function's type.

Correcting these types uncovered a real bug in `wp_mime_type_icon()`: when an attachment ID matched no icon, the `wp_mime_type_icon` filter received an undefined `$icon`, so `null` along with a warning. It now always receives `string|false`, and values read from the object cache are only used when they are strings. The `is_object()` guard in `_set_preview()` is removed, since `WP_Query` only applies the `the_preview` filter to a post already passed through `get_post()`, and no plugin in the directory was found to return anything else from it. Conditional return types are also added to `get_post_gallery()` and `sanitize_term()`, so callers get the type matching the arguments they pass.

The `wp_imagecreatetruecolor()` error moves to the permanent ignore list, because PHPStan analyzes against PHP 7.4, where `imagecreatetruecolor()` returns a resource rather than a `GdImage`.

Developed in #15387.
Follow-up to r63023, r63941.

Props mukesh27, westonruter.
See #65817.


git-svn-id: https://develop.svn.wordpress.org/trunk@65410 602fd350-edb4-49c9-b593-d223f7449a82
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Nov 12, 2026
Every `return.unusedType` error is fixed and its baseline removed. Most came from a `@return` tag that listed a type the function never returns. Others came from a filter `@param` tag that listed too few types: PHPStan derives the result of `apply_filters()` from the hook's first `@param`, so where the function's documented return was already right, the hook docs were corrected instead of loosening the function's type.

Correcting these types uncovered a real bug in `wp_mime_type_icon()`: when an attachment ID matched no icon, the `wp_mime_type_icon` filter received an undefined `$icon`, so `null` along with a warning. It now always receives `string|false`, and values read from the object cache are only used when they are strings. The `is_object()` guard in `_set_preview()` is removed, since `WP_Query` only applies the `the_preview` filter to a post already passed through `get_post()`, and no plugin in the directory was found to return anything else from it. Conditional return types are also added to `get_post_gallery()` and `sanitize_term()`, so callers get the type matching the arguments they pass.

The `wp_imagecreatetruecolor()` error moves to the permanent ignore list, because PHPStan analyzes against PHP 7.4, where `imagecreatetruecolor()` returns a resource rather than a `GdImage`.

Developed in WordPress/wordpress-develop#15387.
Follow-up to r63023, r63941.

Props mukesh27, westonruter.
See #65817.

Built from https://develop.svn.wordpress.org/trunk@65410


git-svn-id: http://core.svn.wordpress.org/trunk@64549 1a063a9b-81f0-0310-95a4-ce76da25c4cd
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