fix(i18n): defer translations until init to silence WP 6.7 textdomain notice#1166
fix(i18n): defer translations until init to silence WP 6.7 textdomain notice#1166superdav42 merged 1 commit intomainfrom
Conversation
… notice
WordPress 6.7 added a _doing_it_wrong notice when a plugin triggers
the just-in-time textdomain loader before the 'init' action fires.
Two paths in Ultimate Multisite were calling __() too early:
1. WPEngine_Integration::__construct() built the description with __()
inline and called set_description(). Integration_Registry instantiates
every provider on plugins_loaded priority 9, before init.
Fix: follow the lazy pattern already used by the other 16 integration
providers — override get_description() so the translation runs only
when the wizard or admin UI requests it (always after init).
2. The WP_CLI trait's enable_wp_cli() registered commands synchronously
from each Manager's init() (called during plugin bootstrap, also
before the init action). Each registration passed translated
shortdescs through __() and sprintf(__(...)).
Fix: enable_wp_cli() now schedules a single add_action('init', ...)
at priority 0; the heavy registration moves into a new
register_wp_cli_commands() method that runs on the init hook. WP-CLI
still sees the commands because its own command dispatch happens after
WordPress finishes bootstrapping.
Verified by instrumenting WP's gettext filter to log any translation
attempted before did_action('init'): 6+ events on origin/main, 0 events
after this change. wp wu sub-commands still register and run normally.
📝 WalkthroughWalkthroughThis PR introduces two independent refactorings: WP-CLI command registration is deferred to WordPress's ChangesDeferred WP-CLI Command Registration
Lazy Description Loading in WPEngine Integration
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@inc/integrations/providers/wpengine/class-wpengine-integration.php`:
- Around line 49-59: The public method get_description in
class-wpengine-integration.php should not declare a PHP return type; remove the
": string" return type from the get_description method signature so the method
matches the coding guideline for inc/integrations/ and remains extensible by
addons that may override it.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: b63ad9ab-9d74-4ba0-9f48-c6886941ed72
📒 Files selected for processing (2)
inc/apis/trait-wp-cli.phpinc/integrations/providers/wpengine/class-wpengine-integration.php
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function get_description(): string { | ||
|
|
||
| $description = __('WP Engine drives your business forward faster with the first and only WordPress Digital Experience Platform. We offer the best WordPress hosting and developer experience on a proven, reliable architecture that delivers unparalleled speed, scalability, and security for your sites.', 'ultimate-multisite'); | ||
|
|
||
| $description .= '<br><br><b>' . __('We recommend to enter in contact with WP Engine support to ask for a Wildcard domain if you are using a subdomain install.', 'ultimate-multisite') . '</b>'; | ||
|
|
||
| return $description; | ||
| } |
There was a problem hiding this comment.
Remove PHP return type declaration from public method.
The : string return type on line 52 violates the coding guideline for this directory. As per coding guidelines, public methods in inc/integrations/ must not use PHP return type declarations because external addons may extend these classes, and PHP will fatal if child classes don't match the parent's return type signature.
🔧 Proposed fix
/**
* {`@inheritdoc`}
+ *
+ * `@return` string
*/
- public function get_description(): string {
+ public function get_description() {📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** | |
| * {@inheritdoc} | |
| */ | |
| public function get_description(): string { | |
| $description = __('WP Engine drives your business forward faster with the first and only WordPress Digital Experience Platform. We offer the best WordPress hosting and developer experience on a proven, reliable architecture that delivers unparalleled speed, scalability, and security for your sites.', 'ultimate-multisite'); | |
| $description .= '<br><br><b>' . __('We recommend to enter in contact with WP Engine support to ask for a Wildcard domain if you are using a subdomain install.', 'ultimate-multisite') . '</b>'; | |
| return $description; | |
| } | |
| /** | |
| * {`@inheritdoc`} | |
| * | |
| * `@return` string | |
| */ | |
| public function get_description() { | |
| $description = __('WP Engine drives your business forward faster with the first and only WordPress Digital Experience Platform. We offer the best WordPress hosting and developer experience on a proven, reliable architecture that delivers unparalleled speed, scalability, and security for your sites.', 'ultimate-multisite'); | |
| $description .= '<br><br><b>' . __('We recommend to enter in contact with WP Engine support to ask for a Wildcard domain if you are using a subdomain install.', 'ultimate-multisite') . '</b>'; | |
| return $description; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@inc/integrations/providers/wpengine/class-wpengine-integration.php` around
lines 49 - 59, The public method get_description in
class-wpengine-integration.php should not declare a PHP return type; remove the
": string" return type from the get_description method signature so the method
matches the coding guideline for inc/integrations/ and remains extensible by
addons that may override it.
SummaryFix the WordPress 6.7+ SymptomRoot cause (reproduced)Instrumented WordPress's
Changes
|
|
Performance Test Results Performance test results for 2d78204 are in 🛎️! Note: the numbers in parentheses show the difference to the previous (baseline) test run. Differences below 2% or 0.5 in absolute values are not shown. URL:
|
Summary
Fix the WordPress 6.7+
_load_textdomain_just_in_timedoing_it_wrong notice for theultimate-multisitetext domain by deferring two paths that translated strings before theinitaction fires.Symptom
Root cause (reproduced)
Instrumented WordPress's
gettextfilter to log any__()call made beforedid_action('init'). Onorigin/maintwo distinct call sites trigger early translations on every request:WPEngine_Integration::__construct()atinc/integrations/providers/wpengine/class-wpengine-integration.php:35,37.Integration_Registry::fire_registration_hooks()is hooked toplugins_loadedpriority 9, which instantiates 17 provider classes — only WPEngine sets its description with inline__()instead of overridingget_description()(the lazy pattern used by the other 16 providers).WP_CLItraitenable_wp_cli()atinc/apis/trait-wp-cli.php:79,95,100,130-150,178,193,212,221,237. Every Manager'sinit()synchronously callsenable_wp_cli()during plugin bootstrap, which calls__()while registering WP-CLI command shortdescs. WP-CLI's own bootstrap loads WordPress beforeinitfires, so the textdomain just-in-time loader trips the WP 6.7 notice on every WP-CLI run.Trace excerpt (reproduced locally on WP 7.x dev install):
Changes
inc/integrations/providers/wpengine/class-wpengine-integration.php__()calls from the constructor.get_description()override that runs the translations on demand. This matches the pattern already used by Closte, Cloudways, RunCloud, cPanel, ServerPilot, GridPane, Cloudflare, Hestia, Enhance, Plesk, Rocket, WPMUDEV, BunnyNet, LaravelForge, Amazon SES, and CyberPanel — WPEngine was the odd one out.inc/apis/trait-wp-cli.phpenable_wp_cli()keeps its public signature so every existing Manager continues to call it frominit()unchanged.add_action('init', [$this, 'register_wp_cli_commands'], 0).register_wp_cli_commands()method holds the original registration logic (the__()calls move into it). It runs oninitpriority 0, before WP-CLI dispatches commands, sowp wu …continues to work without any other code change.Verification
init):wp wulists all sub-commands (customer, membership, payment, product, registered_domain, site, webhook).wp wu customer list --format=countruns cleanly.vendor/bin/phpcs inc/integrations/providers/wpengine/class-wpengine-integration.php inc/apis/trait-wp-cli.php→ clean.vendor/bin/phpstan analyse inc/integrations/providers/wpengine/class-wpengine-integration.php inc/apis/trait-wp-cli.php→ no errors.vendor/bin/phpunit --filter 'Integration_Registry_Test|Provider_Integration_Test|Event_Manager_Test'→ 127 tests, 1 unrelated pre-existing failure (amazon-ses missing domain-mapping capability, also fails onorigin/main).Notes
enable_wp_cli()signature is preserved; the only behavioural difference is that command registration now happens oninitpriority 0 rather than synchronously during the Manager'sinit()method.register_wp_cli_commands()ispublicbecause the trait may be used by classes that compose it differently; the method is referenced only via theadd_actioncallback.aidevops.sh v3.15.12 plugin for OpenCode v1.14.41 with claude-sonnet-4-6 spent 13h 24m and 40 tokens on this as a headless worker.
Summary by CodeRabbit