Opened 12 months ago
Closed 5 months ago
#4564 closed Defect (fixed)
elgg_echo in REST calls only returns default language
| Reported by: | mikehedman | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | Elgg 1.8.12 |
| Component: | Core | Version: | 1.8.4 |
| Severity: | minor | Keywords: | REST elgg_echo |
| Cc: | brett@… | Difficulty: |
Description
Strings returned from REST calls don't seem to be respecting the user's preferred language, and instead are returned in the default language.
At the beginning of the startup process for handling the REST call, Elgg cycles through the init functions, and in users_init's call to elgg_register_widget_type, it calls elgg_echo for the first time. At this stage, there's no session, no cookies, and no user (yet), so ultimately get_language() just picks the default language, which elgg_echo then sets the static $CURRENT_LANGUAGE to.
Subsequent calls then use the default language.
I think the root issue is that we shouldn't be setting static variables during the init process.
Just removing the call to elgg_echo from users_init won't be sufficient, as we have internal plugins which also call elgg_register_widget_type with elgg_echo, so I think the solution will have to be a little deeper. Maybe wrap elgg_echo's setting of $CURRENT_LANGUAGE to only set once the boot process is complete.
Change History (7)
comment:1 Changed 12 months ago by markharding
comment:2 Changed 12 months ago by mikehedman
@markharding - putting up a full example would be a bit hard. Here's a made up sample which displays the problem
expose_function("login", "rest_login",
array("username" => array('type' => 'string'),
"password" => array('type' => 'string')),
'logs in the user',
'POST', false, false);
function rest_login($username, $password) {
$auth_token = auth_gettoken($username, $password);
if ($auth_token) {
return elgg_echo('loginok');
} else {
return false;
}
}
Then, in a unit test:
public function testLogin() {
$user = $this->users[self::TEST_USER];
$user->language = 'de';
$user->save();
$data = array('method' => 'login',
'username' => self::TEST_USER,
'password' => self::TEST_PASSWORD);
$json = $this->post($this->apiJsonUrl, $data);
$values = json_decode($json, TRUE);
reload_all_translations(); //make sure German is available
$this->assertEquals(elgg_echo('loginok', array(), $user->language), $values['result']);
}
We expect that the loginok string will be returned in German, but it comes back in English.
I hope this helps. And YES, this is just a made up scenario, this isn't really how we do our logging in :)
comment:3 Changed 12 months ago by markharding
From what I can gather, it's using the site default language because no PAM session is in place - no user is logged in yet. If, for example, you use OAuth with a valid access token then it sill show the users preferred language, just as it would in an elgg view.
comment:4 Changed 11 months ago by cash
- Milestone changed from Needs Review to Elgg 1.8.6
Confirmed. The problem is with the caching of the translations (it works with system cache turned off).
comment:5 Changed 6 months ago by mrclay
- Milestone changed from Elgg 1.8.9 to Elgg 1.8.10
comment:6 Changed 6 months ago by brettp
- Milestone changed from Elgg 1.8.10 to Elgg 1.8.12
comment:7 Changed 5 months ago by brettp
- Resolution set to fixed
- Status changed from new to closed
This looks like it was fixed in 4c391e8cbdfb7a51392244d3f3ff0af35b1adb88. I couldn't reproduce on latest 1.8 branch.

can you provide an example?