Skip to content

Fix i18n locale fallback and missing-locale retry spam - #543

Merged
kilbot merged 3 commits into
mainfrom
codex/fix-i18n-locale-fallback-pr
Feb 18, 2026
Merged

Fix i18n locale fallback and missing-locale retry spam#543
kilbot merged 3 commits into
mainfrom
codex/fix-i18n-locale-fallback-pr

Conversation

@kilbot

@kilbot kilbot commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add regional locale fallback in PHP i18n loading (da_DKda) before giving up
  • cache missing locale/version combinations to avoid repeated CDN requests and repeated log spam on every init
  • suppress expected intermediate 404 log entries during fallback attempts
  • add regression tests for locale fallback and missing-locale caching behavior

Test plan

  • Run composer run lint
  • Run pnpm run pretest
  • Run pnpm run test:unit:php
  • In a WordPress site using locale da_DK, confirm WCPOS loads da translations when da_DK files are unavailable
  • In a locale with no translations, confirm only the first check attempts CDN downloads; subsequent requests in the cache window do not repeat the same i18n download/log cycle

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Improvements
    • Regional locale variants (e.g., en_US) now fall back to base-language translations (e.g., en) when region-specific files are unavailable.
    • Translation loading prefers an up-to-date local file, with fallback to a stale local file if needed to avoid gaps.
    • Missing-locale results are cached to prevent repeated download attempts, improving performance and reliability.
    • Reduced noisy error logs during harmless fallback attempts.
@coderabbitai

coderabbitai Bot commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉


📝 Walkthrough

Walkthrough

Introduces per-locale candidate fallback (regional → base language), per-locale missing-locale caching, and per-locale download/load logic in the i18n module; expands tests to validate fallback and missing-locale caching behavior.

Changes

Cohort / File(s) Summary
i18n core changes
includes/i18n.php
Added MISSING_LOCALE_CACHE_TTL constant; new helpers get_locale_candidates, load_translation_file, get_missing_locale_transient_key; changed download_translation signature to accept suppress_404_logs and record last_download_status_code; implemented per-locale candidate loading, stale-file fallback, per-locale version/transient handling, and conditional 404 suppression/logging.
Tests: locale fallback & caching
tests/includes/Test_i18n.php
Clears additional transients in setup; added test_regional_locale_falls_back_to_base_language and test_missing_locale_is_cached_to_avoid_repeated_download_attempts to verify candidate fallback order, suppressed 404 behavior during fallbacks, and caching of missing locales to avoid repeated downloads.

Sequence Diagram

sequenceDiagram
    participant Client
    participant i18n as i18n Module
    participant Cache as Transient Cache
    participant FS as File System
    participant Remote as Remote Server

    Client->>i18n: request translations for locale (e.g., da_DK)
    activate i18n

    i18n->>i18n: get_locale_candidates(da_DK) => [da_DK, da]
    i18n->>Cache: check missing-locale transient for da_DK
    Cache-->>i18n: miss

    i18n->>FS: load_translation_file(da_DK, file)
    FS-->>i18n: not found / stale

    i18n->>Remote: download_translation(da_DK, file, suppress_404_logs=true)
    Remote-->>i18n: 404 (recorded in last_download_status_code)

    i18n->>FS: load_translation_file(da, file)
    FS-->>i18n: found (or downloaded)
    i18n->>Cache: set missing-locale transient for da_DK with version (MISSING_LOCALE_CACHE_TTL)

    i18n->>Client: translations loaded (using da)
    deactivate i18n
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped from da_DK to da with care,
Sniffed transients hiding in the air,
If 404s whisper, I note the score,
Cache the miss, and skip the chore—
Hooray, translations found somewhere! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: regional locale fallback support and caching of missing locales to prevent retry spam.
Docstring Coverage ✅ Passed Docstring coverage is 81.82% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/fix-i18n-locale-fallback-pr

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0224bc4939

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread includes/i18n.php Outdated
// Ensure file uses WordPress 6.5+ format (messages key) before loading.
if ( file_exists( $file ) ) {
$this->maybe_convert_file_format( $file );
set_transient( $this->get_missing_locale_transient_key( $requested_locale ), $this->version, self::MISSING_LOCALE_CACHE_TTL );

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Cache missing locale only on definitive 404 failures

This writes the *_missing_* transient after any failed download sequence, but download_translation() returns false for temporary failures too (network WP_Error, 5xx, empty body, filesystem write issues), not just locale-not-found 404s. In those transient outage scenarios, the locale is incorrectly marked as missing for a day, so future initializations skip CDN retries and keep serving stale/no translations even after the backend recovers. Restrict missing-locale caching to cases where all candidates fail with 404.

Useful? React with 👍 / 👎.

@github-actions

github-actions Bot commented Feb 18, 2026

Copy link
Copy Markdown
Contributor

PHPUnit Test Results

    8 files  ± 0    360 suites  ±0   10m 1s ⏱️ -30s
  758 tests + 3    750 ✅ + 3   8 💤 ±0  0 ❌ ±0 
6 064 runs  +24  6 000 ✅ +24  64 💤 ±0  0 ❌ ±0 

Results for commit b260bc4. ± Comparison against base commit dd60980.

♻️ This comment has been updated with latest results.

@kilbot
kilbot merged commit 4fc3991 into main Feb 18, 2026
15 checks passed
@kilbot
kilbot deleted the codex/fix-i18n-locale-fallback-pr branch February 18, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant