Repository navigation
Date/Time: Refine WP_Locale parameter types and handle invalid date inputs. - #14827
rootzero00 wants to merge 9 commits into
Conversation
Trac ticket: https://core.trac.wordpress.org/ticket/64522 WordPress.org contributor: raulsalvat
|
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: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. Props Bot commandsYou can trigger Props Bot actions by commenting on this PR:
|
This comment has been minimized.
This comment has been minimized.
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. |
westonruter
left a comment
There was a problem hiding this comment.
While we're here, we should go ahead and update the other methods with similar type narrowings. For example, the get_meridiem() method should add a:
@phpstan-param 'am'|'pm'|'AM'|'PM' $meridiem
Same for the other methods where relevant. I think get_month() and get_month_genitive() are the other candidates.
The `start_of_week` option is cast to an int but otherwise unchecked, so a negative value makes `( $wdcount + $week_begins ) % 7` negative, and a value above 6 is out of range for `WP_Locale::get_weekday()`. Either leads to an undefined array key. Clamping it to 0-6 keeps the weekday headers valid and satisfies the new `int<0, 6>` type of `WP_Locale::get_weekday()`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…kday_date(). `get_post_time()` returns false when the post date cannot be parsed. Both functions passed that straight to `WP_Locale::get_weekday()`, where it was coerced to the array key 0, so the post was silently labeled Sunday. Now nothing is output in that case, and the filterable string result is cast and clamped to 0-6 to match the `int<0, 6>` type of `WP_Locale::get_weekday()`. This removes the corresponding entry from the `argument.type` PHPStan baseline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For each format character whose output has a fixed range, such as `w` for `'0'` through `'6'` or `m` for `'01'` through `'12'`, the conditional return type now gives that range, mirroring what PHPStan infers for `DateTimeInterface::format()`. Formats with an open-ended numeric output give `numeric-string`. Formats that `wp_date()` translates (`D`, `l`, `M`, `F`, `a`, and `A`) and the PHP 8.2+ `X` and `x` remain `string`. With `w` narrowed, the weekday number passed to `WP_Locale::get_weekday()` in the_weekday() and the_weekday_date() already satisfies `int<0, 6>` after an int cast, so the `clamp()` calls are no longer needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…int in wp_date(). `DateTimeInterface::format( 'w' )` returns a string from `'0'` to `'6'`, which worked only because the string was coerced to an integer array key. Casting it to an int matches the `int<0, 6>` parameter type and removes the last `get_weekday()` entry from the `argument.type` PHPStan baseline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arsed. `wp_date()` only checked the timestamp with `is_numeric()`, which accepts values that `date_create( '@' . $timestamp )` rejects, such as `'1e3'`, `1e20`, `' 5'`, and `'.5'`. For those, `date_create()` returned false and the following `setTimezone()` call caused a fatal error. Now false is returned, as documented for invalid timestamp input and as already done for non-numeric input. This also resolves the PHPStan `method.nonObject` errors on every use of `$datetime` in the function. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Unlike the other `WP_Locale` getters, `get_month()` returns an empty string for a month number that is not found, which was added so that callers like `single_month_title()` can pass unvalidated query var values. Narrowing its parameter to valid month numbers told callers to validate input the method already handles, surfacing errors at call sites that pass `zeroise()` results, query vars, or database values. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
🤖 Comment by Claude Opus 5.5 Several follow-up changes were made while reviewing the new Changes
Upstream PHPStan fix for
|
| File | Count | Trunk message |
|---|---|---|
src/wp-includes/functions.php |
1 | Parameter #1 $weekday_number of method WP_Locale::get_weekday() expects int, string given. |
src/wp-includes/general-template.php |
2 | Parameter #1 $weekday_number of method WP_Locale::get_weekday() expects int, string|false given. |
Level 10
| Trunk base | PR head | With follow-ups | |
|---|---|---|---|
| Errors | 1955 | 1964 | 1950 |
Fixed relative to the PR head: 14 errors
| Identifier | Count | Where (line numbers at the PR head) |
|---|---|---|
argument.type |
6 | get_month() given non-empty-string, non-falsy-string, string|false, or int: src/wp-admin/export.php:167, src/wp-admin/includes/class-wp-list-table.php:815, src/wp-admin/includes/media.php:2969, and src/wp-includes/general-template.php:1653, 1951, and 2740 |
argument.type |
1 | get_weekday() given int<-6, 6>: src/wp-includes/general-template.php:2749 |
method.nonObject |
7 | Cannot call method …() on DateTime|false. on every use of $datetime in wp_date(): src/wp-includes/functions.php:261, 264, 271, 272, 289, 292, and 308 |
Seven more errors at the PR head are not fixed but go back to their trunk wording, because get_month() again expects int|string: the six mixed arguments from query vars and database rows (general-template.php:1661, 1948, 2381, 2851, and 2863, and media.php:5062) and the zeroise() call inside get_month().
Relative to trunk: 7 fixed, 2 introduced
- Fixed: the 7
method.nonObjecterrors inwp_date()listed above. - Introduced: 2
argument.typeerrors forget_meridiem()atsrc/wp-includes/functions.php:294and297, which Infer literal types for word date format characters phpstan/phpstan-src#6838 resolves. - Unchanged apart from wording: the
zeroise()call inget_month_genitive()now reportsint<1, 12>|string giveninstead ofint|string given.
|
@rootzero00 please able maintainer edits for this PR and others as that will facilitate getting changes into core. |
|
🤖 Comment by Claude Opus 5.5 PHPStan 2.3.3 has been released, and it includes phpstan/phpstan-src#6838 (fixing phpstan/phpstan#15537). PHPStan now infers literal types for the word date format characters ( That resolves the two
The branch was analyzed with PHPStan 2.3.2 and then with 2.3.3. The analyzed branch was this PR's head e26b0b9 with
The upgrade introduces no errors anywhere else in the codebase. Once PHPStan is bumped to 2.3.3 in |
|
@rootzero00 Please turn on maintainer edits for this PR. |
Refines weekday, genitive-month, and meridiem parameter types using PHPStan-specific annotations while preserving standard @PARAM tags. get_month() retains its full string|int input type and unknown-month fallback.
Integrates Weston's six follow-up commits from rootzero00#1:
Trac ticket: https://core.trac.wordpress.org/ticket/64522
Verification
Candidate: e26b0b9
Verification executed in the Codex environment:
GitHub Actions results must be assessed for this exact candidate separately.
Contributor: Raul Salvat. Requested WordPress.org props: raulsalvat.
Integrated follow-up commits retain Weston Ruter's authorship and existing attribution.
Use of AI Tools
AI assistance: Yes.
Tools: ChatGPT/Codex; integrated follow-up commits retain their Claude Code attribution.
Used for preparing the original annotation change, reviewing and validating the follow-ups, integrating existing commits, and preparing PR metadata. Original server commands were executed by the contributor; the candidate verification described above ran in the Codex environment.
This pull request is for code review only. Please keep other discussion in the Trac ticket; do not merge this pull request on GitHub.