Jump to content

User language always fall back to default after login in frontend


Juergen
 Share

Recommended Posts

I have searched the forum but I havent found a solution or explaination for this behaviour.

I have setted up a multlingual site with English and German (=default). Therefore I have included a language switcher in the frontend which works quite well.

In the backend a user can select the language in his profile  (in my case English and German).

For example a user choose English as his prefered language this value will be stored in the db.

PROBLEM:

If a user logs in in frontend  (not in backend) and he logs out after a while, the user language which is stored in the database will fall back to default (German).

So if the user is logging in the next time (in backend or in frontend) - he can see that the language has changed from English to German - THIS IS NOT WHAT I WANT. The stored language in the user profile should be untouched.

I dont know why the stored user language value falls back to the default language in the db, but it happens all the time and this drives me crazy.

Has anyone an idea how to solve this problem or why this always happens?

Best regards Jürgen

Link to comment
Share on other sites

Sorry,

I use PW 2.4 with PHP 5.4

The language of each user ist stored in the table "field_language" and in the row "data". Therefore I have made an standard SQL-query to output the stored user language in the frontend.

Code:

$loginuser = $user->id;// fe user with the id 41
$sql = "SELECT data FROM field_language WHERE pages_id=$loginuser";
$result = wire('db')->query($sql);
list($data) = $result->fetch_row();
$userlanguageindb = $data;
echo $userlanguageindb; // gives me the language id for the user

This piece of code output the stored language id (in my case 1011 for English) in the frontend template, but this id changes so the default language id must be stored in the db.

I think the PW language module is responsible for the issue, because i dont push a submit button to store something in the database.

Link to comment
Share on other sites

So first of all, it seems your quite new to ProcessWire. You don't need to query the database to get the data, the processwire api does this for you. The query's on the thread I linked before where only to find the source of the misbehavior. If you need more information relating to the api have a look here: http://processwire.com/api/.

To get the current language of a user you only need to look at "$user->language", which outputs the stored language. You can also set another language via the api like so. 

$user->language = $languages->get("default");
$user->save();

Unfortunatly in 2.4 seems to be an error in the code, which prevents saving of the right language in some cases. This is investigated in the thread I linked before.

Link to comment
Share on other sites

Thanks LostKobrakai,

no I dont trigger the db ususally in this way. I know that I can make the db-calls like $user->id, $user->pass and so on.

I only made this to check if there is an difference (and there were differences without refreshing the page) in the output between the PM-call and the SQL query.

I think you are right - there is a bug in the last version as discussed here https://github.com/ryancramerdesign/ProcessWire/issues/409

but I cannot get it to work after the changes I made in the pages.php

Link to comment
Share on other sites

The only other issue I can imagine to influence the language would be a language agnostic url. If you use a different url for the translated content, this will automatically change the value of $user->language to reflect the current page language. 

If this doesn't help with your issue, you should try to pin down when/where the language exactly gets reseted. Your title suggests, that before your login script the language is still the right one, even in the db, while after it's called, it's the wrong one. If you would provide some detailed information about the "before-login" and "after-login" state and the login script itself, maybe the issue can be tracked down to it's source.

Link to comment
Share on other sites

Thanks for your efforts,

yes I use different urls for the pages such as www.mydomain/de/profil/ (German) and www.mydomain/en/profile/ (English).

And yes the correct language is set BEFORE the login process and changes after the login in FRONTEND.

I made a simple Bootstrap 3 Login form with the fields username and password which redirects after successfull login to the user profile page (FRONTEND).

There the user can change several data such as username, email address and so on.

Today I will let it as it is, but tomorrow I will try to trace the problem down to its source.

Best regards Jürgen

Link to comment
Share on other sites

And why do you use a bootstrap to login? In a bootstrap there's no language/page context.

I think he's talking about the bootstrap framework and not about actually bootstraping pw. 

@Juergen

It would be nice if you could provide the code of your login process. Could it be, that your redirecting always to the default language's url?

Link to comment
Share on other sites

Yes I am talking about the Bootstrap framework of Twitter and here is the code I use for the login form.

<?php

$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();

$profile = $pages->get(1084);
$profileurl = $profile->url;
$resetpass = $pages->get(1080);
$resetpasseurl = $resetpass->url;
$anmelden = __('Bitte anmelden');
$fehlgeschlagen = __('Fehlgeschlagen');

// set all variables for labels and others
$hinweistext = __("pflichtfeldhinweis");
// Output labels in correct language
$usernamelabel = __("username placholder");
$passwordlabel = __("password placeholder");
$hiddenfieldlabel = __("Leave empty");
$loginbuttontext = __("anmeldebutton");
$iconusername = "asterisk";
$iconpassword = "asterisk";


$usernamedesc = __("username desc");
$passworddesc = __("password desc");

 
if($user->isLoggedin()) $session->redirect($profileurl);

$hinweis = '<p>'.$hinweistext.'</p>';

if (isset($_POST['submit'])) {

/*instantiate variables taking in the form data */
    $username = $_POST['login-name'];
    //$username = $sanitizer->username($username);
    $pass = $_POST['pass'];
    
    if($username && $pass) {//password and username are entered
      
     
     $u = $users->get($username);
     if($u->id && $u->tmp_pass && $u->tmp_pass === $pass) {
     // user logging in with tmp_pass, so change it to be their real pass
     $u->of(false);
     $u->pass = $u->tmp_pass;
     $u->save();
     $u->of(true);       
     }
      
     $u = $session->login($username, $pass);   
     if($u) {
     // user is logged in, get rid of tmp_pass
     $u->of(false);
     $u->tmp_pass = '';
     $u->save();
     // now redirect to the profile edit page
     $session->redirect($profileurl);
     } else {
     $error1 = "1";        
     $matcherrormessage = __("pw und name stimmen nicht überein");
     $matcherror ="<p>'.$matcherrormessage.'</p>";  
     }

} else {

    if (!$username){//username empty
    $error2 = "1";
    $message = __('username fehlt');
    $usernameerrormessage = '<p class="control-label"><b><span class="fa fa-warning"></span> '.$message.'</b></p>';
    } else {
    $error2 = "0";
    }
    if (!$pass){//password empty
    $error3 = "1";
    $message = __('password fehlt');
    $passworderrormessage = '<p class="control-label"><b><span class="fa fa-warning"></span> '.$message.'</b></p>';
    }
    if($pass AND(strlen($pass)< 6)){
      $error4 = "1";   
      $passwordlengthmessage = __("password must contain length of 6");                    
      $passwordlengtherrormessage = '<p class="control-label"><b><span class="fa fa-warning"></span> '.$passwordlengthmessage.'</b></p>';
      }
      else {
      $error4 = "0";
      }             
}
    //create css error classes
    if ($error1 OR $error2){
    $usernameclass = " has-error";
    $iconusername = "times";
    $usernamevalue = "";
    } else {
    $usernameclass = " has-success";
    $iconusername = "check";
    $usernamevalue = $username;
    }
    if ($error1 OR $error3 OR $error4){
    $passwordclass = " has-error";
    $iconpassword = "times";
    $passwordvalue = "";
    } else {
    $passwordclass = " has-success";
    $iconpassword = "check";
    $passwordvalue = $pass;
    }    
    
    $errornumber = $error1 + $error2 + $error3 + $error4;
    $generalerrormessage1 = __("Es sind");
    $generalerrormessage2 = __("Fehler aufgetreten");
    $headline = __("Fehlgeschlagen");
    $warning = __("warning");
    $errorsmessage .= "<div class='alert alert-danger' role='alert'><h4><i class='fa fa-warning'></i> $warning</h4><p>$generalerrormessage1 <span class='badge'>$errornumber</span> $generalerrormessage2</p>$matcherror</div>";

$form .= "<form id='login-form' name='subscribe-form' method='post' action='./' role='form'>
             <div class='form-group$usernameclass'>
             <label class='hidden control-label' for='username'>$usernamelabel</label>
             $usernameerrormessage
                   <div class='input-group'>
               <span class='input-group-addon' title='$usernamedesc' data-toggle='tooltip'><span class='fa fa-question-circle'></span></span>
               <input id='login-name' class='form-control' value='$usernamevalue' name='login-name' maxlength='2048' placeholder='$usernamelabel' type='text'>
                   <span class='input-group-addon'><span class='fa fa-$iconusername'></span></span>
               </div>
             </div>
             
             <div class='form-group$passwordclass'>
             <label class='hidden control-label' for='pass'>$passwordlabel</label>
             $passworderrormessage
             $passwordlengtherrormessage
                   <div class='input-group'>
               <span class='input-group-addon' title='$passworddesc' data-toggle='tooltip'><span class='fa fa-question-circle'></span></span>             
               <input id='pass' class='form-control' value='$passwordvalue' name='pass' maxlength='2048' placeholder='$passwordlabel' type='password'>
                   <span class='input-group-addon'><span class='fa fa-$iconpassword'></span></span>
               </div>
             </div>
    
                  <button id='Inputfield_submit' class='btn btn-default' name='submit' value='$loginbuttontext' type='submit'>$loginbuttontext</button>
            <input type='hidden' id='_post_token' name='TOKEN$token' value='$token' />        
          </form>";
    
    

 

 

} else {
$headline .= __("Bitte anmelden");
$form .= "<form id='login-form' name='login-form' method='post' action='./' role='form'>
             <div class='form-group'>
             <label class='hidden control-label' for='login-name'>$usernamelabel</label>
                   <div class='input-group'>
               <span class='input-group-addon' title='$usernamedesc' data-toggle='tooltip'><span class='fa fa-question-circle'></span></span>
               <input id='login-name' class='form-control' name='login-name' maxlength='2048' placeholder='$usernamelabel' type='text'>
                   <span class='input-group-addon'><span class='fa fa-asterisk'></span></span>
               </div>
             </div>
             
             <div class='form-group'>
             <label class='hidden control-label' for='pass'>$passwordlabel</label>
                   <div class='input-group'>
               <span class='input-group-addon' title='$passworddesc' data-toggle='tooltip'><span class='fa fa-question-circle'></span></span>
               <input id='pass' class='form-control' name='pass' maxlength='2048' placeholder='$passwordlabel' type='password'>
                   <span class='input-group-addon'><span class='fa fa-asterisk'></span></span>
               </div>
             </div>
    
                  <button id='Inputfield_submit' class='btn btn-default' name='submit' value='$loginbuttontext' type='submit'>$loginbuttontext</button>
            <input type='hidden' id='_post_token' name='TOKEN$token' value='$token' />        
          </form>";

}




//$changepassword = "<p><a title='' href='/de/passwort-andern/' rel='nofollow'>";

$forgotpass .= __("Zugangsdaten vergessen");
$page->body = '<article class="container maincontent anmeldung" role="main">
 <div class="row">
 <div class="col-md-12">
 <h1>'.$headline.'</h1>'.$hinweis.$errorsmessage.''.$form.'<br /><p><a href="'.$resetpasseurl.'" rel="nofollow">'.$forgotpass.'</a></p>
 </div>
 </div>
 </article>';
 
include("./inc/head.inc");
echo $page->body;
include("./inc/foot.inc");
?>

I use not the form api of PW because I want to use the Bootstrap markup - this is the reason why the code is such long. I make all the validations via PHP and not with the built in validations of PW (because of the use of Bootstrap :) ).

Best regards Jürgen

Link to comment
Share on other sites

Just to clarify, PW doesn't save something on it's own unless you do. And it has nothing to do with Twitter Bootstrap of course...

So as we see it's in your code that does save the user. Unfortunately PW2.4 there was a bug (linked above) that seems to be the issue here. 

Link to comment
Share on other sites

Hello Soma,

yes I know that Boostrap has nothing to do with it. But as you can see there is no code in it that makes a save in the database, its only a making of queries against the db, so nothing will be stored in it. I will check the profile template tomorrow (this is where the users will be redirected after the successfull login). I will try to figure out when the moment is where the language will be changed in the db.

Best regards Jürgen

Link to comment
Share on other sites

Hello Soma,

yes I know that Boostrap has nothing to do with it. But as you can see there is no code in it that makes a save in the database, its only a making of queries against the db, so nothing will be stored in it. I will check the profile template tomorrow (this is where the users will be redirected after the successfull login). I will try to figure out when the moment is where the language will be changed in the db.

Best regards Jürgen

What about the two times in your code where you do $u->save(), doesn't that save something in DB? ;)

Don't think you'll find the issue (apart from that it's something already fixed), as it's quite a complex issue. But if you read the bug report you'll maybe understand, that saving the user will set the language to default for various reasons how the system is built.

Maybe you're able to just use the pre 2.5 dev (very stable), or try work around it by setting the user language before saving, but doubt it will work as the issue is on saving a page (users are pages) on front-end using multilanguage. 

  • Like 1
Link to comment
Share on other sites

Hello Soma,

I think I am going to update to the dev-version. Its seems to be the best way in this case.

What about the two times in your code where you do $u->save(), doesn't that save something in DB? ;)

You are right - the second one saves independent if you are logging in with your standard password or your temp password. I only took a look at the first one which is in an if-statement and has no influence by logging in with the standard password.

Best regards Jürgen

Link to comment
Share on other sites

I have traced the problem down. As Soma pointed out the cause is the save command in the login form. I have tested it with phpmyadmin and the database change is after the login as a cause of the $u->save() process.

Here is the solution for this issue from this discussion: https://github.com/ryancramerdesign/ProcessWire/issues/409

First of all download the new file from here: https://github.com/ryancramerdesign/ProcessWire/blob/a411e2523f5f14d2354f40a661e41503595a890a/wire/core/Pages.php

Go to wire/core and find the Pages.php. Replace the code with the code downloaded above

After this the userlanguage will not change after frontend login. It stays the same in the database.

Alternatively, as Soma pointed out too, you can update to 2.5 dev-version, but I have not tested it.

Best regards Jürgen

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...