I am running CI version 2.1 and I have recently installed the CodeIgniter 2.1 internationalization i18n (Original Author: Jérôme Jaglale). The code instructions are here: http://codeigniter.com/wiki/URI_Language_Identifier/
It runs fine but I would like to override the default language if the user set his language preference in a previous visit to the website (this would be stored in a table in the database).
My question is, how do you do this?
I believe MY_Lang.php (where default language is loaded) is actually loaded BEFORE the CodeIgniter MY_Controller so I am unable to load the database to find if a user has a preferred language.
The default language is configured in MY_Lang.php here:
function default_lang()
{
$browser_lang = !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? strtok(strip_tags($_SERVER['HTTP_ACCEPT_LANGUAGE']), ',') : '';
$browser_lang = substr($browser_lang, 0,2);
$default_lang = array_splice(array_keys($this->languages), 0,1);
return (array_key_exists($browser_lang, $this->languages)) ? $browser_lang : $default_lang[0];
}
However, I am unable to override it because here I have no access to my $this->session->userdata('language')
Thanks in advance!
ANSWER HERE:
Found out that you can use native PHP cookies to read the cookie inside MY_Lang.php file. If you try to use the cookie helper it won't work, so make sure you use $_COOKIE instead and run the appropriate filters before getting the content.
Then, in MY_Lang.php just change this:
return (array_key_exists($browser_lang, $this->languages)) ? $browser_lang : $default_lang[0];
To this:
if($_COOKIE['int_lang']) {
$preferred_lang = filter_var($_COOKIE['int_lang'], FILTER_SANITIZE_STRING);
return (array_key_exists($preferred_lang, $this->languages)) ? $preferred_lang : $default_lang[0];
}
else
{
return (array_key_exists($browser_lang, $this->languages)) ? $browser_lang : $default_lang[0];
}
If it was me, I'd use cookies for that instead of storing this in a database. It'll be faster and easier to manage.
Most users don't erase cookies, at least not all that often. It would solve your problem: "I am unable to load the database to find if a user has a preferred language".
If you need the database storage, you could try using a Hook:
http://codeigniter.com/user_guide/general/hooks.html
In a "post_controller_constructor" hook, load you Database Model used for language storage, get the language set by the user and load the language file that you want.
Related
I am a Java developer (I often used Spring MVC to develop MVC web app in Java) with a very litle knowledge of PHP and I have to work on a PHP project that use CodeIgniter 2.1.3.
So I have the following doubt about how exactly work this controller method:
So I have this class:
class garanzieValoreFlex extends CI_Controller {
.....................................................
.....................................................
.....................................................
public function index() {
$this->load->model('Direct');
$flagDeroga = "true" ;
$this->session->userdata("flagDeroga");
$data = $this->session->userdata("datiPreventivo");
$this->load->model('GaranzieValoreFlexModel');
$data = $this->session->userdata("datiPreventivo");
$this->load->model('GaranzieValoreFlexModel');
$this->load->view('garanziavalore/index_bootstrap',$data);
}
}
I know that the index() method of the garanzieValoreFlex controller class handle HTTP Request toward the URL: http://MYURL/garanzieValoreFlex and show the /views/garanzievalore/index_bootstrap.php page.
It works fine. The only think that I can't understand is what exactly does this code line:
$data = $this -> session -> userdata("datiPreventivo");
Can you help me what exactly is doing? I think that it is putting something into the HttpSession or something like this but I am absolutly not sure about it and I can't understand the logic.
session is a Codeigniter (CI) library (class) that allows data to persist across multiple page calls from a browser. In the version of CI you are using "native" PHP session functionality is not used. But CI's session class does mimic PHP's session in that data is stored in a PHP associative array.
The class has many different methods to store and retrieve user defined data. The function userdata("index_to_data") is one of the main class methods. It is used to retrieve data that has been stored in the session class.
The argument passed to userdata() is the key to a value in the session class array $userdata. So, $this->session->userdata("datiPreventivo"); returns the value stored at $userdata["datiPreventivo"]. If the key (in this case "datiPreventivo") does not exist then $this->session->userdata("datiPreventivo") returns FALSE.
Somewhere in the code you are working with you will find a line where data is stored in the session. The line of code might look something like this.
$newdata = array("datiPreventivo" => $something_value);
$this->session->set_userdata($newdata);
Searching your code for "$this->session->set_userdata" might be helpful to understand what exactly is being saved for future page loads.
It is important to know that CI's session class was completely rewritten in versions > 3.0 so the current documentation may not be very helpful to you. You will need to find the documentation for the version you are using to learn more about the session library. I believe that documentation is included in the download for your version which can be found here.
This is rather a call for testimonies than a real questions. I would greatly appreciate feedbacks from CI experts and fans.
I have been searching the Internet for hours about this issue of mine: getting CI Form Validation class load the proper language file dynamically.
Let me explain. In my config.php file, I have:
$config['language'] = 'english';
Which is indeed the default language. But I have implemented a Settings controller which is letting my users set some values and of course change their default language. I could have stored that setting into a session variable but for the moment I don't, I just load that language user setting into each controller within the constructor :
$this->idiom = get_user_setting('language');
$this->lang->load('main', $this->idiom);
$this->lang->load('settings', $this->idiom);
$this->lang->load('cst', $this->idiom);
and as you can see I then load all the language files I need for each controller with the appropriate language. The 'get_user_setting' function is just a helper of mine querying the database to get a particular setting id.
I have copied the form_validation_lang.php from the /system/language/english/ directory and put it into my /application/language/french/ directory, and then I thought doing the following would do the magic:
$this->lang->load('form_validation', $this->idiom);
But nope... does not change anything. I took a look at the Form Validation class in the core folder and saw the following:
// Load the language file containing error messages
$this->CI->lang->load('form_validation');
THis clearly makes me think it will always load the file of the default language set in the config.php file. Am I right or wrong?
Hence, the only way I got to have this work with my user defined settings I fetch from the database (and which I could also store in a session variable), is to do the following:
$this->idiom = get_user_setting('language');
$this->config->set_item('language', $this->idiom);
...
I would greatly appreciate some feedbacks if some of you already had to cope with this kind of requirements and if you indeed managed that the same way I did or not. If I'm totally wrong, I'd appreciate solutions of course.
THanks a lot for your help.
Yes form_validation load default language file.If you want to load different language you can do a trick or change the source code of the Form validation class.
The trick I use, change the default language before using form validation(you can change back after form validation complete if you need.)
You can change default language with this code.
$this->config->set_item('language', 'YOUR_LANGUAGE');
After this code you can use form validation which will load the language you set.
Here is the way I solved it:
Create your own application\libraries\My_Form_validation.php.
Copy over the run() method from system\libraries\Form_validation.php into your file.
Change the following line in the run() method in your file from:
$this->CI->lang->load('form_validation');
To:
$language = !empty($this->CI->session->language) ? $this->CI->session->language : 'english';
$this->CI->lang->load('form_validation', $language);
This is assuming you are storing the language in the sessions. In your case you would do $language = get_user_setting('language'); I assume.
I'm using the TYPO3\CMS\Fluid\View\StandaloneView in a CommandController to send emails to my fe_user.
The part where im building the template looks like this:
/* #var \TYPO3\CMS\Fluid\View\StandaloneView $emailView */
$emailView = $this->objectManager->get( 'TYPO3\\CMS\\Fluid\\View\\StandaloneView' );
// pass extension name to standaloneView for translations
$extensionName = $this->request->getControllerExtensionName();
$emailView->getRequest()->setControllerExtensionName( $extensionName );
$extensionPath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath( 'my_extension' );
$templatePathAndFilename = $extensionPath . 'Resources/Private/Templates/Email/' . $templateFile . '.html';
$emailView->setLayoutRootPath( $extensionPath . 'Resources/Private/Layouts/Email/' );
//$emailView->setPartialRootPath($ressourcePath . 'Partials/');
$emailView->setTemplatePathAndFilename( $templatePathAndFilename );
return $emailView->render();
Nothing special i think.
In the html-Template i'm using the normal translate ViewHelper of Fluid:
<f:translate key="LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:mail.text" />
This all works well in the standard language, but i've no idea how i can tell the View/CommandController which language to use.
I'm not quite sure if this is a StandaloneView or a CommandController problem...
Edit:
The posted snippet is called from the CommandController (Scheduler) - so there is no current frontend user (we are in backend environment). I get the user from a repository so i've to save the selected language in there. But then i've to set the language for the StandaloneView
Generally you can set the language in a CommandController by doing this:
$GLOBALS['BE_USER']->uc['lang'] = 'de';
The problem is that the LocalizationUtility creates a cache for the extension after it's been called once to ::translate() something. There is no available function to reset that cache, but you can add this little utility function in your extension to enable you to do just that:
namespace Vendor\Extension\Utility;
class LocalizationUtility extends \TYPO3\CMS\Extbase\Utility\LocalizationUtility
{
public static function resetExtensionLangCache($extensionName){
unset(static::$LOCAL_LANG[$extensionName]);
}
}
If you have the case where you have to switch the full language context in your CommandController you can now call this right after switching the language for the BE_USER:
\Vendor\Extension\Utility\LocalizationUtility::resetExtensionLangCache('<extensionname>');
This will reset the cache and LocalizationUtility will have to initialize its entry for your extension until you switch and call it again.
To control the language used in a Fluid StandaloneView from the backend context, just set the language as shown below (I set the language to german).
$GLOBALS['BE_USER']->uc['lang'] = 'de';
This should be set before you call the $emailView->render() method.
I assume, that you want to send an email in language currently used by user, in that case, you should create language config for the additional languages, like described in TYPO3 docs.
When configured properly and non-default language is used, all your views (also these standalone) will be translated to the current language.
AFAUK, there's no way to force translate VH to use some language ie. by giving it's uid.
I am using codeigniter for a project that is used by a variety of companies.
The default version of our software is up and running and works fine - however some of our customers want slightly different view files for their instance of the system.
Ideally what I would like to do is set a variable (for example VIEW_SUFFIX) and whenever a view file is loaded it would first check if there was a suffix version available if there was use that instead.
For example if the system had a standard view file called 'my_view.php' but one client had a VIEW_SUFFIX of 'client_1' - whenever I called $this->load->view('my_view') if the VIEW_SUFFIX was set it would first check if my_view_client_1 existed (and if it did use that) or if not use the default my_view.php.
I hope that my question is clear enough... If anyone has done this before or can think of a way to do it I would really appreciate it.
EDIT:
Ideally I would like a solution that works without me changing every place that I am calling the view files. Firstly because there are a few files that may want different client versions and also because the view files are called from a lot of controllers
I had a similar requirement for which I created a helper function. Among other things, this function can check for a suffix before loading the specified view file. This function can check for the suffix and check if the file exists before loading it.
Unfortunately, the file checking logic would be a bit brittle. As an alternative, you can implement a MY_Loader class that will override the basic CI_Loader class.
Something like this in your application/core/MY_Loader.php:
class MY_Loader extends CI_Loader {
protected function _ci_load($_ci_data)
{
// Copy paste code from CI with your modifications to check prefix.
}
}
Could you not do this
// some method of creating $client
// probably created at login
$_SESSION['client'] = 'client_1';
$client = (isset($_SESSION['client'])) ? $_SESSION['client'] : '';
$this->load->view("your_view{$client}", $data);
The Magento backend allows you to disable module output per site. I've done some Google searches but can't figure out how to grab this value through my code. Basically when my module's output is disabled that works just fine. But I've discovered (the hard way) that Magento doesn't prevent the module from loading per-site.
Because I'm extending some core classes, some constructors are still being executed. My thought is to check if the module output is disabled. If so, have my constructor call the parent's constructor. If the module output is enabled, proceed with my custom code.
I just can't figure out how to grab this value for the current site (I am multi-sited, BTW). Ideally it would be something like this:
$isThisEnabled = Mage::app()->getCurrentStore()->isOutputEnabled('myModule');
Basically have a single line that fetches the current site's value (or the default, if not specified for the current site).
Any help would be greatly appreciated!
EDIT: I found the table core_config_data, which appears to store this information. I could manually query it if I had to, but I feel like Magento would have something built-in to return the current store's value, falling back to the default value.
It is a standard config setting, so accessing it should be no different than accessing any other config setting. You just need to know what is the path to this value. Analysing the DB I believe this should do the trick:
Mage::getStoreConfig('advanced/modules_disable_output/Namespace_Module');
The other option is that the Mage_Core_Helper_Abstract has an isModuleEnabled($moduleName = null) method, which means that you should be able to call:
Mage::helper('core/data')->isModuleEnabled('Namespace_Module')
There is also a isModuleOutputEnabled() method. Looking at the code, these don't seem to be filtered by store/view, whereas #silvo's method is.
<?php
public function mycontrollerAction()
{
$moduleName = 'Namespace_Modulename';//eg Mage_Cms
if(Mage::getConfig()->getModuleConfig($moduleName)->is('active', 'true'))
{
echo "Module Enable";
}
else
{
echo "Module Disable";
}
}
?>