Codeinwp / Codeinwp/tweet-old-post
WPML 5.0: restoring language by code leaves WPML switched, breaks language restore after sharing
Nobody has claimed this yet.
- Dominant language
- PHP
- Stars
- 13
- Forks
- 15
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 8
Description
Description
WPML 5.0 changes the semantics of the wpml_switch_language action. Passing a language code now opens a nested language scope, and only passing null closes one. Restoring the previous language by re-passing the saved code, which is what ROP does today, no longer restores anything. It opens a second scope and leaves WPML switched to that language for the rest of the request.
WPML errata: https://wpml.org/errata/restoring-the-language-by-name-leaves-wpml-switched/
We received a heads-up from the WPML compatibility team about this ahead of the 5.0 release (internal ref: HelpScout ticket 3447373140).
Affected code
All in includes/admin/models/class-rop-posts-selector-model.php:
get_taxonomies(): saves the current language, switches to the account or post format language (lines 108 and 123 on current master), then "restores" it by passing the saved code back toswitch_language()(line 171).select(): same pattern; switches at line 372, restores by code at line 461 on current master. This one runs on every cron share for every account that has a WPML language set in its post format.switch_language()(line 1079 on current master) is the shared helper both paths use; the WPML branch callsdo_action( 'wpml_switch_language', $language_code ).
Impact on WPML 5.0 sites
After each ROP share cycle or Post Format screen load on a site with language based sharing configured, the site is left switched to the account's language instead of being restored. On cron runs with multiple accounts, scopes stack up within the request. The failure is silent: sharing itself still works, but any code running after ROP in the same request (other plugins, the rest of the cron batch, subsequent accounts' queries) sees the wrong language.
Proposed fix
Add a restore path that closes the scope the way WPML 5.0 expects:
- WPML branch: call
do_action( 'wpml_switch_language', null )to restore, instead of passing the saved code. - TranslatePress branch: keep the current behavior (
trp_switch_language( $saved_code )), TRP has no scope semantics and needs the explicit code.
Simplest shape: add a restore_language( $saved_code ) method next to switch_language() that branches on TRP vs WPML, and replace the three restore call sites with it.
Open question for the fix
Behavior of wpml_switch_language( null ) on WPML 4.x needs to be verified before release. If null does not restore correctly on 4.x, the restore path needs a WPML version check (e.g. on ICL_SITEPRESS_VERSION).
Also worth checking while testing against 5.0
ROP detects WPML via function_exists( 'icl_object_id' ) throughout. WPML 5.0 removes some legacy icl_* entry points (the icl_ajx_action and icl_tm_action routers). We have no indication icl_object_id is removed, but a quick check on a 5.0 site that the WPML integration still activates would rule it out.
Testing notes
- Site with WPML, two languages, ROP Pro license active (language based sharing is gated to Pro license types).
- Set a WPML language on one account's post format.
- Trigger a share, then inspect the current WPML language after
select()returns (e.g.apply_filters( 'wpml_current_language', null )on a later hook in the same request). - On WPML 4.x current code passes; on WPML 5.0 the language stays switched without this fix.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in includes/admin/models/class-rop-posts-selector-model.php, reading get_taxonomies(), select(), and the shared switch_language() helper. Trace the three restore call sites and verify WPML 4.x and 5.0 behavior for wpml_switch_language(null), while preserving TranslatePress restoration. Test a share and a post-format load, then confirm the language after select() returns.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, wordpress
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100