Repository navigation
Conversation
|
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. |
Co-authored-by: Weston Ruter <westonruter@gmail.com>
|
If it weren't for the
With the changes here, And no PHPStan error is raised. Separately from the changes here, I want to improve the |
| * @type string $show_option_none Text to display for showing no categories. Default 'Select Category'. | ||
| * @type string $id Value for the 'id' attribute of the select element. | ||
| * } | ||
| * @param array $instance Array of settings for the current widget. |
There was a problem hiding this comment.
Might as well type this as well
There was a problem hiding this comment.
I found an issue with HashNotationVisitor which I want to fix as part of this. Currently, Keys of a @param hash are optional, at every level. But this is not always the case. For \WP_Widget_Categories::widget(), these args are always passed:
* @param array $args {
* Display arguments.
*
* @type string $before_widget HTML markup to prepend to each widget in the sidebar.
* @type string $after_widget HTML markup to append to each widget in the sidebar.
* @type string $before_title HTML markup to prepend to the widget title when displayed.
* @type string $after_title HTML markup to append to the widget title when displayed.
* }
Maybe there should be a way to denote “Required” args explicitly in this notation. Either this, or we just go ahead and use PHPStan notation instead.
There was a problem hiding this comment.
I'm going ahead with adding this. We can address the new PHPStan errors (at higher rule levels) in a subsequent commit.
Describe the keys passed in `$cat_args` to the `widget_categories_args` filter, matching the documentation already added for the `widget_categories_dropdown_args` filter, including the boolean types of `show_count` and `hierarchical`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add `@since 7.2.0` entries to the `widget_categories_dropdown_args` and `widget_categories_args` filters, noting that `show_count` and `hierarchical` are now passed as booleans rather than numeric strings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
🤖 Comment by Claude Opus 5.5 PHPStan impact at rule level 10Updated for 5d41db6. The earlier version of this comment covered 3eddf65, before the widget instance, PHPStan was run on
All of the changes are in Fixed (14)
Introduced (7)
The 5 errors that are actually new are not problems in the code. They come from two limits of how hash notation is translated: there is no way to mark A real case that this kind of analysis exposed was fixed in 8697d5b: |
|
🤖 Comment by Claude Opus 5.5 Back-compat reviewThis PR changes CoreNo impact. Plugins and themes (Veloria)Callbacks on the two widget filters. About 40 plugins and 50 themes in the WordPress.org directories reference
Strict comparisons anywhere. A search was run for
Other minor differences
ConclusionNo breaking change was found. The only visible effect is the Hideo markup change described above. |
Describe the `title`, `count`, `hierarchical` and `dropdown` keys of the widget instance wherever it is passed: `widget()`, `form()`, `update()` (including the submitted settings and the returned array), and the `$instance` parameter of the `widget_categories_dropdown_args` and `widget_categories_args` filters. The flags are documented as `int|string` on input, since `update()` saves them as `0` or `1` but `the_widget()` can pass them as strings parsed from a query string. This removes 7 PHPStan errors at rule level 10 in the file. It surfaces 2 others in `update()`, which reflect limits of how hash notation is translated rather than wrong documentation: keys of a `@param` hash are always optional, so reading `$new_instance['title']` is flagged, and a `@return` hash is sealed, while `update()` also carries over any other keys in `$old_instance`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Narrow `count`, `hierarchical` and `dropdown` in the documented widget instance from `int|string` to `int`, which is what `update()` saves. A string only arrives when `the_widget()` is given a query string, which `wp_parse_args()` turns into string values, and that usage is not one the types should accommodate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`update()` only ever stores `count`, `hierarchical` and `dropdown` as `0` or `1`, so document them with that literal type rather than `int`, which also makes the "Accepts 0 or 1" text redundant. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A checkbox in the widget form has no `value` attribute, so it submits `'on'` when checked and is omitted when unchecked. The block-based widget editor also resubmits the saved instance through the REST API, which passes the stored `0` or `1` to `update()` as `$new_instance`. Document both instead of a generic `string`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The documented instance types say `count`, `hierarchical` and `dropdown` are `0|1`, so note why `widget()` still reads them with `! empty()`: the keys are missing on an unsaved instance, instances saved before WordPress 2.8 (r10809) stored booleans, and `the_widget()` passes values through as its caller supplies them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describe the `before_widget`, `after_widget`, `before_title` and `after_title` keys of the `$args` passed to `widget()`. This removes 5 PHPStan errors at rule level 10 and surfaces 4 `offsetAccess.notFound` errors where those keys are read. Keys of a `@param` hash are always translated as optional, while core always passes these four, so the new errors reflect that limit of the hash notation tooling rather than a problem in the code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`MockAction::get_args()` returns `mixed`, so PHPStan reported every offset read on the captured `$cat_args` and its `array_keys()` call. Assert that it is an array first, which narrows the type and checks that the filter received one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `widget_categories_args` and `widget_categories_dropdown_args` tests cast `show_count` and `hierarchical` to `bool` before asserting, so they would still pass if `widget()` went back to passing `'1'` and `'0'`. Compare the raw values so the type change is covered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `widget_categories_dropdown_args` filter's `$cat_args` go to `wp_dropdown_categories()`, which documents options such as `show_option_all`, `selected` and `value_field` that `WP_Term_Query` does not. Reference it for the additional accepted arguments, as the `widget_categories_args` docs do with `wp_list_categories()`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The widget always sets `show_option_none` to 'Select Category'; it is not a fallback. If a callback removes it, `wp_dropdown_categories()` uses its own default of an empty string, so the option disappears. Describe the value as set rather than as a default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Instances saved before WordPress 2.8 stored `count` and `hierarchical` as booleans, which is one reason `widget()` reads them with `! empty()`. Cover both `true` and `false` in the widget options data provider so the filter-args and list-output tests exercise that back-compat case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Add coverage for updates where the widget title is omitted.
0 open findings
What changed in this PR
Updates WP_Widget_Categories to use boolean category arguments while preserving legacy widget compatibility.
Changes:
- Converts category flags to booleans.
- Handles missing widget titles safely.
- Adds compatibility and boolean-behavior tests.
| File | Summary |
|---|---|
tests/phpunit/tests/widgets/wpWidgetCategories.php |
Verifies boolean arguments and legacy instances. |
src/wp-includes/widgets/class-wp-widget-categories.php |
Converts widget flags and updates documentation. |
🧠 Review effort: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
`update()` falls back to an empty title when `$new_instance` has no `title` key, as when REST form data omits it. Add a data provider case for that, which fails with an undefined array key warning if the fallback is removed, and which also checks that the old title is cleared rather than kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Categories widget passed `show_count` and `hierarchical` to `wp_list_categories()` and `wp_dropdown_categories()` as the numeric strings `'0'` and `'1'`, while both functions document these arguments as `bool|int`. They are now passed as booleans, matching what the Categories block already passes. Core only checks these values for truthiness, so output is unchanged; a callback on the `widget_categories_args` or `widget_categories_dropdown_args` filter that compares them strictly to `'1'` or `'0'` is the only code affected, which is noted in the filters' `@since` tags. The arguments passed to those filters, along with the widget's display arguments and instance settings, are now documented as hashes so that static analysis can type them. The `count`, `hierarchical` and `dropdown` settings are documented as the `0` or `1` that `update()` stores, while `widget()` keeps reading them loosely for instances saved before WordPress 2.8, which stored booleans. A missing title in the submitted settings no longer triggers an undefined array key warning in `update()`, which can happen when REST API form data omits it. Developed in #8071. Follow-up to r10809, r41685, r64331. Props westonruter, marian1. See #65817, #65860. Fixes #62762. git-svn-id: https://develop.svn.wordpress.org/trunk@64413 602fd350-edb4-49c9-b593-d223f7449a82
The Categories widget passed `show_count` and `hierarchical` to `wp_list_categories()` and `wp_dropdown_categories()` as the numeric strings `'0'` and `'1'`, while both functions document these arguments as `bool|int`. They are now passed as booleans, matching what the Categories block already passes. Core only checks these values for truthiness, so output is unchanged; a callback on the `widget_categories_args` or `widget_categories_dropdown_args` filter that compares them strictly to `'1'` or `'0'` is the only code affected, which is noted in the filters' `@since` tags. The arguments passed to those filters, along with the widget's display arguments and instance settings, are now documented as hashes so that static analysis can type them. The `count`, `hierarchical` and `dropdown` settings are documented as the `0` or `1` that `update()` stores, while `widget()` keeps reading them loosely for instances saved before WordPress 2.8, which stored booleans. A missing title in the submitted settings no longer triggers an undefined array key warning in `update()`, which can happen when REST API form data omits it. Developed in WordPress/wordpress-develop#8071. Follow-up to r10809, r41685, r64331. Props westonruter, marian1. See #65817, #65860. Fixes #62762. Built from https://develop.svn.wordpress.org/trunk@64413 git-svn-id: http://core.svn.wordpress.org/trunk@63563 1a063a9b-81f0-0310-95a4-ce76da25c4cd
Trac ticket: https://core.trac.wordpress.org/ticket/62762
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.