Fix email report decimal comma locale. - #13265
Conversation
📦 Build files for 747d030:
🎭 Playwright reports for 747d030: |
tofumatt
left a comment
There was a problem hiding this comment.
I'd expect some test cases with large numbers here to ensure we're handling both decimal places and thousands separators properly, and I've left some notes about comments and approach here.
| $change = $data['change'] ?? null; | ||
| if ( null !== $change ) : |
There was a problem hiding this comment.
What's with the indentation here? It seems a bit off 🤔
Also, will $data[ 'change' ] ever be null of its own accord? If not:
| $change = $data['change'] ?? null; | |
| if ( null !== $change ) : | |
| if ( undefined !== $data['change'] ) : |
seems like it would work 🤔
| $change = $data['changes'][ $index ] ?? null; | ||
| if ( null !== $change ) : |
There was a problem hiding this comment.
Similarly, is this casting to null needed? If so: can you add a comment explaining why?
| * @var float $value The percentage change value. Callers must guard against | ||
| * `null` and skip rendering this part entirely when no | ||
| * comparison is available, rather than passing a | ||
| * default of `0`, which would render a misleading `0%` | ||
| * badge. |
There was a problem hiding this comment.
| * @var float $value The percentage change value. Callers must guard against | |
| * `null` and skip rendering this part entirely when no | |
| * comparison is available, rather than passing a | |
| * default of `0`, which would render a misleading `0%` | |
| * badge. | |
| * @var float $value The percentage change value. Callers must guard against | |
| * `null` and skip rendering this part entirely when no | |
| * comparison is available, rather than passing a | |
| * default of `0`, which would render a misleading `0%` | |
| * badge. |
Why not have this component accept undefined/null values and choose to output nothing? 🤔
| $formatted = number_format( $number, 2, '.', '' ); | ||
|
|
||
| $output[] = sprintf( '%s%%', $formatted ); |
There was a problem hiding this comment.
Is there any reason to format this as a string at all here? Why not just return the float and do the locale-formatting later on, if this one isn't locale-aware anyway? 🤔
| * | ||
| * The trend is kept in a canonical, period-decimal form rather than a | ||
| * locale-formatted one, since downstream consumers (the template | ||
| * formatter and the change-badge template) always re-parse and | ||
| * re-format the value themselves. A locale-formatted string (e.g. | ||
| * `6,52%` under a decimal-comma locale) only made the value harder to | ||
| * re-parse. |
There was a problem hiding this comment.
This looks like an AI-generated comment and is a bit too verbose. It's documenting, very specifically, the behaviour of this function in the context of this issue's fix, but it doesn't serve the reader of this documentation in-general.
| * | |
| * The trend is kept in a canonical, period-decimal form rather than a | |
| * locale-formatted one, since downstream consumers (the template | |
| * formatter and the change-badge template) always re-parse and | |
| * re-format the value themselves. A locale-formatted string (e.g. | |
| * `6,52%` under a decimal-comma locale) only made the value harder to | |
| * re-parse. |
| // `es_CO` is not an installed test locale, but `normalize_trends()` | ||
| // must not localize the trend regardless of what the active | ||
| // locale's number format looks like (simulated above), so the | ||
| // locale name here only documents intent. |
There was a problem hiding this comment.
| // `es_CO` is not an installed test locale, but `normalize_trends()` | |
| // must not localize the trend regardless of what the active | |
| // locale's number format looks like (simulated above), so the | |
| // locale name here only documents intent. | |
| // Simulate the `es_CO` locale, which uses commas | |
| // for decimals (eg. `6,52`, not `6.52`). |
| public function data_parse_change_value() { | ||
| $cases = array(); | ||
| $values = array( | ||
| '6.52%' => 6.52, | ||
| '-0.85%' => -0.85, | ||
| '6,52%' => 6.52, | ||
| '-0,85%' => -0.85, | ||
| '0%' => 0.0, | ||
| ); |
There was a problem hiding this comment.
As mentioned earlier: some larger values with both commas and decimals should be used here to ensure they behave properly.
| * rather than relying on `switch_to_locale()`, which silently no-ops for | ||
| * locales without an installed translation file. |
There was a problem hiding this comment.
| * rather than relying on `switch_to_locale()`, which silently no-ops for | |
| * locales without an installed translation file. | |
| * rather than relying on `switch_to_locale()`, which proceeds without warnings | |
| * for locales without an installed translation file. |
| * rather than relying on `switch_to_locale()`, which silently no-ops for | ||
| * locales without an installed translation file. | ||
| * | ||
| * @param string $locale Locale name (en_US, es_CO, or de_DE). |
There was a problem hiding this comment.
| * @param string $locale Locale name (en_US, es_CO, or de_DE). | |
| * @param string $locale Locale name (eg. `'en_US'`, etc.). |
| // The email's static <style> block always defines `.badge-positive`/ | ||
| // `.badge-negative` CSS rules, so assert on the rendered `class` | ||
| // attribute rather than the bare class name. |
There was a problem hiding this comment.
| // The email's static <style> block always defines `.badge-positive`/ | |
| // `.badge-negative` CSS rules, so assert on the rendered `class` | |
| // attribute rather than the bare class name. | |
| // The email's static <style> block always defines `.badge-positive`/ | |
| // `.badge-negative` CSS rules, so include the `class=""` wrapper to | |
| // ensure we're testing for the existence of the badge markup and not | |
| // just the CSS in the `<style>` tag. |
Summary
Related issue(s):
Relevant technical choices
normalize_trends()now formats trends withnumber_format()(period decimal) instead ofnumber_format_i18n(), since the locale-formatted string (e.g.6,52%) couldn't be re-parsed byis_numeric()and silently became0%.parse_change_value()detects the decimal separator structurally instead of assuming one, so it parses both the new canonical format and any legacy locale-formatted values already stored.section-metrics.php/section-page-metrics.phpskip the change badge entirely when the value isnull, instead of defaulting to0.build_sections()switches the locale but never restores it on success, so it can leak into later renders — tracked in Email report section builder leaks switched locale on success path #12883.-0%for a trend that rounds to negative zero — tracked in Email report change badge shows -0% for near-zero negative trends #13264.PR Author Checklist
Do not alter or remove anything below. The following sections will be managed by moderators only.
Code Reviewer Checklist
Merge Reviewer Checklist