Codeinwp / Codeinwp/tweet-old-post

WPML 5.0: restoring language by code leaves WPML switched, breaks language restore after sharing

Open
#1,132 0 comments 0 reactions 0 assignees View on GitHub

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:

  1. 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 to switch_language() (line 171).
  2. 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.
  3. switch_language() (line 1079 on current master) is the shared helper both paths use; the WPML branch calls do_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
  1. Site with WPML, two languages, ROP Pro license active (language based sharing is gated to Pro license types).
  2. Set a WPML language on one account's post format.
  3. 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).
  4. On WPML 4.x current code passes; on WPML 5.0 the language stays switched without this fix.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.