Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Form validation ignores language when changed during run-time

I'm using CodeIgniter to build a multilanguage web application. I have English and other languages under /system/languages/ folder and I've created a model responsible for changing the working language at run-time.

By default CodeIgniter is working in French as defined in /application/config/config.php

$config['language'] = 'french';

Later, according to a URI segment the model changes the language accordingly, simplified example bellow:

class multilang extends CI_Model {
    public function __construct() {
        parent::__construct();
        if ($this->uri->segment(1) == 'en') {
            $this->config->set_item('language', 'english');
        }
    }
}

This model is the first model listed under the auto load settings in /application/config/autoload.php and I can confirm that the language is indeed changed dynamically by calling:

echo $this->config->item('language');

However the built in form validation library does not take into account the changed language, instead only shows error messages from the language hard coded in the settings file /application/config/config.php in this case French.

At first I assumed this was because the form validation was loaded before the multilang model. To make sure the model was loaded first, I modified the form validation constructor to load the model before anything else like this:

public function __construct($rules = array())
{
    $this->CI =& get_instance();
    $this->CI->load->model('multilang');
    // normal code after....
}

This made sure the model loaded before the form validation. Unfortunately this wasn't enough and the form validation still ignores the language when changed during run-time. Anyone knows why this happens?

Thank you.

like image 999
Fábio Antunes Avatar asked Sep 27 '22 13:09

Fábio Antunes


1 Answers

The problem was that I was doing AJAX requests that didn't took into account the URI segment that contained the language abbreviation, because the URI for AJAX requests didn't needed the language segment in the first place, so I totally forgot about it.

Therefore I used the session cookie to store the language. Changing the multilang constructor to:

class multilang extends CI_Model {
    public function __construct() {
        parent::__construct();

        # store lang between session
        $data = $this->session->all_userdata();

        if (isset($data['language'])) {
            $lang = $data['language'];
            # if lang was changed between sessions
            if ($this->uri->segment(1) == 'fr'){
                $lang = 'french';
            } else if ($this->uri->segment(1) == 'en'){
                $lang = 'english';
            }

            # if lang was changed using one of the lang abbreviations
            # overule session setting
            if ($this->uri->segment(1) == 'en') {
                $lang = 'english';
            } else if ($this->uri->segment(1) == 'fr') {
                $lang = 'french';
            }

            $this->config->set_item('language', $lang);
            $this->session->set_userdata('language', $lang);   
        } else {
            if ($this->uri->segment(1) == 'en') {
                $this->config->set_item('language', 'english');
                $this->session->set_userdata('language', 'english');
            } else if ($this->uri->segment(1) == 'fr') {
                $this->config->set_item('language', 'french');
                $this->session->set_userdata('language', 'french');
            }
        }
    }
}

Note: The change to the form_validation constructor wasn't required.

Answer provided for future reference, and to remind people of little things we miss. It was so obvious right! Well this might help the next one who forgets.

Closing question.

like image 172
Fábio Antunes Avatar answered Oct 06 '22 00:10

Fábio Antunes