Welcome Guest, Not a member yet? Register   Sign In
Auth Shield and multilanguage
#1

Hello all,
I use SHIELD for authorization
My application is multilingual
The [users] table has a [multi] column
How do I set a session from the [multi] column after logging in.
I use entry in:
PHP Code:
BaseController.php
//...

public function initController(RequestInterface $requestResponseInterface $responseLoggerInterface $logger)
{
    // Do Not Edit This Line
    parent::initController($request$response$logger);

    // Add these lines
    $session = \Config\Services::session();
    $language = \Config\Services::language();
    $language->setLocale($session->lang);
}
//... 
Thank you
Reply
#2

(This post was last modified: 06-06-2025, 02:37 AM by InsiteFX. Edit Reason: added helper methods. )

This is how I do it, I have a project working on languages.
If you need something to look at I could put it up for download this weekend.

BaseController:

PHP Code:
<?php

namespace App\Controllers;

use 
CodeIgniter\Controller;
use 
CodeIgniter\HTTP\CLIRequest;
use 
CodeIgniter\HTTP\IncomingRequest;
use 
CodeIgniter\HTTP\RequestInterface;
use 
CodeIgniter\HTTP\ResponseInterface;
use 
Config\App;
use 
Config\Services;
use 
Psr\Log\LoggerInterface;

/**
 * Class BaseController
 *
 * BaseController provides a convenient place for loading components
 * and performing functions that are needed by all your controllers.
 * Extend this class in any new controllers:
 *    class Home extends BaseController
 *
 * For security be sure to declare any new methods as protected or private.
 */
abstract class BaseController extends Controller
{
    /**
    * Instance of the main Request object.
    *
    * @var CLIRequest|IncomingRequest
    */
    protected $request;

    /**
    * An array of helpers to be loaded automatically upon
    * class instantiation. These helpers will be available
    * to all other controllers that extend BaseController.
    *
    * @var list<string>
    */
    protected $helpers = [];

    /**
    * Be sure to declare properties for any property fetch you initialized.
    * The creation of dynamic property is deprecated in PHP 8.2.
    *
    *
    */
    protected object $session;

 
/**
 * @var array|string
 */
 
protected array|string $viewData = [];


 
/**
 * @param  RequestInterface $request
 * @param  ResponseInterface $response
 * @param  LoggerInterface $logger
 * @return void
 */
    public function initController(RequestInterface $requestResponseInterface $responseLoggerInterface $logger): void
    
{
        // Do Not Edit This Line
        parent::initController($request$response$logger);

        // Preload any models, libraries, etc, here.

        // E.g.: $this->session = service('session');
 
    // Ensure that the session is started and running
 
    if (session_status() == PHP_SESSION_NONE) {
 
    $this->session Services::session();
 
    }
 
 
    // Load the Language Library
 
    $lang service('language');
 
    $lang->setLocale($this->request->getLocale());

 
    // Below is used for Language Localization
 
    session()->set('locale'$this->request->getLocale());

 
    // Used in the HTML for the Bootstrap Language Drop Down
 
    $this->viewData['page']    '';
 
    $this->viewData['locale']  $this->request->getLocale();
 
    $this->viewData['dir']      getLangDirection();

 
    // Get the supported locales
 
    $config = new App();
 
    $this->viewData['supportedLocales'] = $config->supportedLocales;
    }

}
  // End of Class BaseController.

/**
 * -----------------------------------------------------------------------
 * Filename: BaseController.php
 * Location: ./app/Controllers/BaseController.php
 * -----------------------------------------------------------------------
 */ 
language_helper:

PHP Code:
<?php

declare(strict_types=1);


/**
 *  getLangDirection ()
 * -----------------------------------------------------------------------
 *
 * This is an array list of Right to Left Languages (RTL).
 */
if ( ! function_exists('getLangDirection'))
{
    /**
    * method ()
    * -------------------------------------------------------------------
    *
    * These are RTL Languages.
    * 
    * @return string
    */
    function getLangDirection(): string
    
{
        $locale service('request')->getLocale();

        $rtl = [
            'ar',      // Arabic (International)
            'ar-AE',    // Arabic (United Arab Emirates)
            'ar-BH',    // Arabic (Bahrain)
            'ar-DJ',    // Arabic (Djibouti)
            'ar-DZ',    // Arabic (Algeria)
            'ar-EG',    // Arabic (Egypt)
            'ar-IQ',    // Arabic (Iraq)
            'ar-JO',    // Arabic (Jordan)
            'ar-KW',    // Arabic (Kuwait)
            'ar-LB',    // Arabic (Lebanon)
            'ar-LY',    // Arabic (Libya)
            'ar-MA',    // Arabic (Morocco)
            'ar-OM',    // Arabic (Oman)
            'ar-QA',    // Arabic (Qatar)
            'ar-SA',    // Arabic (Saudi Arabia)
            'ar-SD',    // Arabic (Sudan)
            'ar-SY',    // Arabic (Syria)
            'ar-TN',    // Arabic (Tunisia)
            'ar-YE',    // Arabic (Yemen)
            'fa-AF',    // Dari/Persian (Afghanistan)
            'fa-IR',    // Persian (Iran)
            'he',      // Hebrew (he)
            'he-IL',    // Hebrew
            'iw',      // Hebrew (iw)
            'kd',      // Kurdish (Sorani) RTL
            'pk-PK',    // Panjabi-Shahmuki (Pakistan)
            'ps',      // Pushto; Pashto
            'ug',      // Uighur; Uyghur
            'ur',      // Urdu
            'ur-IN',    // Urdu (India)
            'ur-PK',    // Urdu (Pakistan)
            'yi',      // Yiddish
            'yi-US',    // Yiddish (United States)
        ];

        // if it's in the array then it's a rtl language
        return in_array($locale$rtl) ? 'rtl' 'ltr';
    }
}

/**
 *  getFlags ()
 * -----------------------------------------------------------------------
 *
 */
if ( ! function_exists('getFlags')) {
/**
 * getFlags ()
 * -------------------------------------------------------------------
 *
 * Flag Icon Flags:
 * Some of the names for locale are wrong this array will fix that!
 *
 * @param string $locale
 * @return string
 */
function getFlags(string $locale ''): string
{
    $flags = [
        'ar'    => 'sa',    // Arabic                sa Saudi Arabia
        'bg'    => 'bg',    // Bulgarian            bg Bulgaria
        'bn'    => 'bd',    // Bengali (Bangla)      bd Bangladesh
        'bs'    => 'ba',    // Bosnian              ba Bosnia and Herzegovin
        'cs'    => 'cz',    // Czech                cz Czech Republic
        'de'    => 'de',    // German                de Germany
        'en'    => 'us',    // English              us United States
        'es'    => 'es',    // Spanish              es Spain
        'fa'    => 'ir',    // Persian (Farsi)      ir Iran
        'fr'    => 'fr',    // French                fr France
        'hu'    => 'hu',    // Hungarian            hu Hungary
        'id'    => 'id',    // Indonesian (id/in)    id Indonesia
        'it'    => 'it',    // Italian              it Italy
        'ja'    => 'jp',    // Japanese              jp Japan
        'lv'    => 'lv',    // Latvian (Lettish)    lv Latvia
        'ml'    => 'in',    // Malayalam            in India
        'nl'    => 'dk',    // Dutch                dk Denmark
        'no'    => 'no',    // Norwegian            no Norway
        'pl'    => 'pl',    // Polish                pl Poland
        'pt'    => 'pt',    // Portuguese (Portugal) pt Portuguese (Portugal)
        'pt-BR' => 'br',    // Portuguese (Brazil)  pt-BR Portuguese (Brazil)
        'ro'    => 'ro',    // Romanian              ro Romania
        'ru'    => 'ru',    // Russian              ru Russia
        'si'    => 'lk',    // Sinhalese            lk Sri Lanka
        'sk'    => 'sk',    // Slovak                sk Slovakia
        'sr'    => 'rs',    // Serbian              rs Serbia
        'sv-SE' => 'se',    // Swedish              se Sweden
        'th'    => 'th',    // Thai                  th Thailand
        'tr'    => 'tr',    // Turkish              tr Turkey
        'uk'    => 'ua',    // Ukrainian            ua Ukraine
        'vi'    => 'vn',    // Vietnamese            vn Vietnam
        'zh-CN' => 'cn',    // Chinese (Simplified)  cn China
        'zh-TW' => 'tw',    // Chinese (Traditional) tw Taiwan
    ];

    return $flags[$locale];

    }
}

/**
 * translateCategories ()
 * -----------------------------------------------------------------------
 * app/Config/Autoload.php
 * Add:
 * public $classmap = [
 *    'GoogleTranslate' => APPPATH . 'ThirdParty/GoogleTranslate.php',
 * ];
 *
 * NOTE:
 * Maximum of 5000, character limit per translate!
 *
 * If too long you can split the string in half.
 */
if ( ! function_exists('translateCategories'))
{
    /**
    * @param  string $source
    * @param  string $target
    * @param  string $text
    * @return string
    * @throws Exception
    */
    function translateCategories(string $source ''string $target ''string $text ""): string
    
{
        $gTranslate service('translate');

        return $gTranslate->translate($source$target$text);
    }
}


// End of language_helper Helper.

/**
 * -----------------------------------------------------------------------
 * Filename: language_helper.php
 * Location: ./app/Helpers/language_helper.php
 * -----------------------------------------------------------------------
 */ 

Should give you an idea of how it works.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#3

Thank you very much Smile
Reply
#4

I'm seeing more questions about multilanguage and people using sessions to mess about with them. I want to point out that there is never a need to check if the session has been initialized. By calling the service, if a session doesn't exist, it will be created. In other words this code is unneeded:

PHP Code:
if (session_status() == PHP_SESSION_NONE) {
    $this->session Services::session();
    

You can always access the session by calling session() helper (the only exception to this is if you need some alternative configuration from the default). Doing $this->session offers no benefit as session returns the shared instance of the session, you're just creating more memory pointers. However, if you insist on doing so there's no need for the if statement. You only require the following (and can proceed to access the session doing $this->session):

PHP Code:
$this->session session(); 

The language library is also loaded automatically and your browser (usually based on operating system settings) is preconfigured in whichever language you natively use. Modern browsers sends an 'Accept-Language' header with their requests (there are other ways as well) to let the server know which language it wishes to see. CodeIgniter can detect this by setting up automatic Content Negotiation. So setting up Content Negotiation to automatic removes this code:

PHP Code:
$lang service('language');
$lang->setLocale($this->request->getLocale()); 

Custom code should only be needed in the (albeit illogical) case where a user wants to see a different language than what his system is configured in. In this case you would modify the request to get the locale from the session data (which would have been actualized via a language selection somewhere on the site) rather than through content negotiation.

I'm only calling this out here (as I've seen this code on another post recently) because this is the "Best Practices" section. CodeIgniter 4 has features which makes these particular things a breeze. Read every page of the docs (there isn't a single one that is superfluous), use the features.
Reply
#5

My code is using them because I also have a filter that depends on knowing thigs about the local.
Plus I also have a flags local section dropdown.
What did you Try? What did you Get? What did you Expect?

Joined CodeIgniter Community 2009.  ( Skype: insitfx )
Reply
#6

There were two points I was making:

1. To modify the session use the helper

You did that: session()->set('locale', $this->request->getLocale());
However, because you initially wrote: $this->session = Services::session(); the prior line should have been: $this->session->set('locale', $this->request->getLocale());
You're using two different techniques to access the session, making the first technique where you've created a protected variable for the session object superfluous. Why access it that way if you'll end up using the helper anyway (which also initializes the session if it needs to)?

2. Content Negotiation is automatic

Your code is set up to do content negotiation automatically: $lang->setLocale($this->request->getLocale());
This implies that the language will ALWAYS be set based on what the browser sends i.e. setting automatic content negotiation to true has the same effect.
You've implied that certain things change are deduced on your application based on the locale, this can always be accessed using the request object so there is no need to store it in the session: service('request')->getLocale();
However, you've also stated there is a dropdown of some sort, presumably to allow the user to change their language from the frontend and thus the need to store it in the session. Assuming that's the case then your prior code for setting the locale should be: $lang->setLocale(session('locale'));
This makes it so that the user's choice of language is the one that dictates how Content Negotiation is handled.

When it comes to Content Negotiation you use one or the other (automatic or user set) i.e. they are mutually exclusive.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB