CodeIgniter - Load language globally (not by file but by folder) - codeigniter

Now:
In the config file you can set a default language:
$config['language'] = 'german';
Every loaded language file is now loaded from the 'german' folder
$this->lang->load('custom_messages');
echo $this->lang->line('hello'); //prints "hallo"
It's easy to change languages locally via
$this->lang->load('custom_messages', 'english');
echo $this->lang->line('hello'); //prints "hello"
Wish:
But I want to change the language system wide (language selection at login) like the config file does. So I don't have to to load every _lang-File one by one with the correct language attribute.
Pseudo-Code (config language -> german)
$this->lang->set('english');
$this->lang->load('custom_messages');
echo $this->lang->line('hello'); //should print "hello"
There is nothing documented for this (in my opinion common) use-case.
This doesn't work:
$this->config->set_item('language', 'english');

I have tested this locally, and it appears that you can change the language using set_item but you'll have to do this before loading the language file.
You can do this in constructor, save current language name in a session then set it in constructor
public function __construct () {
parent::__construct();
$this->config->set_item('language', $this->session->userdata('current_language'));
}
here's my test controller:
public function index()
{
var_dump($this->config->item('language')); // english
$this->config->set_item('language', 'german');
var_dump($this->config->item('language')); // german
$this->lang->load('test');
var_dump($this->lang->line('something')); // german translated line
}

Related

Laravel Get the translations of the application from a package

I am trying to develop a small package in Laravel, but I have the following problem. From my package I need to get the translations that are present in the languages directory:
Example:
myapp/resources/lang
When I make a call as follows to get the translations of a file:
private function getTranslationsFromFile()
{
return Lang::get('auth');
}
It does not return the translations in that file. It only returns auth. In the Laravel languages directory there is that file, but inside the directory en.
So I have defined before getting the translations the default 'locale' so that I can load them from there in this way:
private function getTranslationsFromFile()
{
app()->setLocale('en');
return Lang::get('auth');
}
this way it works fine, but my question is the following, is there no way to load the translations regardless of whether or not the 'locale' is set? I mean, is it not possible to get the translations just by giving it a file path?
Example:
private function getTranslationsFromFile()
{
return Lang::get('en/auth');
}
Thank you very much in advance.
You can certainly do that by leveraging the third and fourth parameter of Lang::get():
This is the method's signature:
get(string $key, array $replace = [], string|null $locale = null, bool $fallback = true)
The third parameter specifies the locale you'd wish to get the translation string for:
Lang::get('auth.failed', [], 'en')
To set a fallback language in case that the translation is not available in the chosen locale, use the fourth parameter:
Lang::get('auth.failed', [], 'en', 'es')

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.
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.

Calling string in separate file in CodeIgniter

I'm building a profanity/racial slur filter for my website. I have it working, but my preg_match string is quite long. I'm just wondering if there is some way to host this long string in a separate file in CodeIgniter and then call it when I need to in the preg_match.
I have googled this and I couldn't find anything, so I thought I would ask here.
What I'm doing now is hosting my string in the model and then calling this:
if(preg_match($filterRegex)){
databaseStuffHere();
}
Here are a few options. Depending on how and where you are using this string and function, one may be better than the others.
Config
You could store the value as a config, in application/config/config.php
$config['filter_regex'] = 'yourReallyLongString';
The primary config is auto-loaded by CodeIgniter, so you can use it like so:
$filterRegex = $this->config->item('filter_regex');
if(preg_match($filterRegex, $subject))
{
databaseStuffHere();
}
Constant
If you're using this long string in several places and it would be useful to have global access, you could define it as as constant in application/config/constants.php. It will also prevent you from accidentally redefining the value.
define('FILTER_REGEX', 'yourReallyLongString');
Then use it with your function like this:
$filterRegex = FILTER_REGEX;
if(preg_match($filterRegex, $subject))
{
databaseStuffHere();
}
Helper
Finally, you could use a helper. You can load the helper when required, or auto-load it. You can create your own helper in application/helpers/. It could look something like this:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('filter_slurs'))
{
function filter_slurs($subject = '')
{
$filter_regex = 'yourReallyLongString';
if (preg_match($filter_regex, $subject))
{
return FALSE;
}
else
{
return TRUE;
}
}
}
Having a function to handle this may make your code easier to follow and more meaningful, for example, in your controller, you could use it like this:
$this->load->helper('slur_filter_helper'); //assumes the helper file is: slur_filter_helper.php
if(filter_slurs($subject))
{
//do something
}
else
{
//do something else
}
You can use it with config file (system/application/config/config.php) to set configuration related variables.
====================== DEFINE WHAT YOU WANT in config.php ===========================
$config['REQUIRED_SRTING'] = 'YOUR_REQUIRED_LONG_STRING_OR_WHAT_YOU_WANT_STORE';
But best place to set constant is
(system/application/config/constants.php) to store site preference constants.
===================DEFINE WHAT YOU WANT in constants.php=========================
define('CONSTANT_STRING','YOUR_REQUIRED_LONG_STRING_OR_WHAT_YOU_WANT_STORE');

Global Variables in CodeIgniter not Working

I want to generate global variables in CodeIgniter by creating my own library and config file. This is what I wrote ini my library file, let's say globalvars.php. I put it in /application/libraries.
class Globalvars{
function __construct($config = array())
{
foreach ($config as $key => $value) {
$data[$key] = $value;
}
$CI =& get_instance();
$CI->load->library('session');
$CI->load->vars($data);
}
}
I want the user id stored in the session to be available in global variable, so I wrote this in my config file. It's named also globalvars.php. It's in /application/config directory.
$config['user']=$this->session->userdata('id');
I then test to see if it's working by write it in my controller this way.
echo $data['user'];
But I get this error in the browser
Message: Undefined property: CI_Loader::$session
Filename: config/globalvars.php
It seems that the session functions is not defined yet. How can I get it work? What have I missed here? Any help would be appreciated.
You cannot use the session library in config file.
The config files are loaded before any libraries, so $this->session is undefined.
The config.php has to be loaded in order for the Session class to even be initialized, as it reads settings from that file.
A lot of issues with this type of thing (setting some "global" data) can be resolved using a base controller, and extending it in your controllers.
// core/MY_Controller.php
MY_Controller extends CI_Controller {
function __construct()
{
parent::__construct(); // Now the Session class should be loaded
// set config items here
}
}
"Normal" controllers will now extend MY_Controller to take advantage of this.
See: http://codeigniter.com/user_guide/general/core_classes.html for more details.
In addition, when you load->vars(), they are available to the view layer only, it does not create a global variable called $data as you seem to be trying to access. If you do this:
$this->load->vars(array('user' => '1'));
You would access it in a file loaded by $this->load->view() like this:
echo $user; // outputs "1"
See: http://codeigniter.com/user_guide/libraries/loader.html
$this->load->vars($array)
This function takes an associative array as input and generates
variables using the PHP extract function. This function produces the
same result as using the second parameter of the $this->load->view()
function above. The reason you might want to use this function
independently is if you would like to set some global variables in the
constructor of your controller and have them become available in any
view file loaded from any function. You can have multiple calls to
this function. The data get cached and merged into one array for
conversion to variables.
I will say that as an experienced Codeigniter user, the concept of a "global vars" class is a bit wonky and probably unnecessary, especially when it's already so easy to get and set config items. You could definitely run into some confusing issues and variable name conflicts with this method (pre-loading lots of view variables on every request).

accessing lang variables from controller + codeigniter

How can I access my lang variables in controller?
function index()
{
$seo_title = $this->lang->line('blablabla');
$data['page_title'] = $seo_title;
$this->load->view('contact/index.php',$data);
}
in my lang file blablabla has string in, and it works well when I call from view file. but when I want to call from controller, it doesnt return anything :(
any idea about problem? appreciate!!
You need to load the language file you want to use before you grab lines from it:
$this->lang->load('filename', 'language');

Resources