-
Notifications
You must be signed in to change notification settings - Fork 2k
Closed
Labels
bugVerified issues on the current code behavior or pull requests that will fix themVerified issues on the current code behavior or pull requests that will fix them
Description
Problem
System does not change incoming request locale with overriding it from outer source (not App config, like database) using filter approach
Describe the bug
- all my routes has {locale} in front as first url segment 'en/dashboard', 'lv/dashboard' etc
- supported locales are stored in local mysql database and managed through admin area
- my project will populate / manage languages only through database and admin area, no need of App config $supportedLocales as client will not change and re-commit files
- to avoid caching locale change in frontend, i have setup mainFilter which caches potential locale change at any point (route) within the system
- IncomingRequest class is initialised before filters, so if my filter override supportedLocales - it does not change in further system loding
CodeIgniter 4 version
4.1.1
Solution 1:
- IncomingRequest class - variable
$validLocaleschange fromprotectedtopublic - this way it is possible to override values if needed
Affected module(s)
/system/HTTP/IncomingRequest.php
https://github.com/codeigniter4/CodeIgniter4/blob/develop/system/HTTP/IncomingRequest.php#L99
Solution 2:
- as App config does not have
$validLocalesvariable - as IncomingRequest class - variable
$validLocalesis not heavily used elsewhere - as IncomingRequest class controller mandatory requests App config as first method param
- remove variable
$validLocalesfrom IncomingRequest class - as IncomingRequest class method setLocale() uses
$validLocales, replace it with already loaded$this->config->supportedLocales
Affected module(s)
/system/HTTP/IncomingRequest.php
remove: https://github.com/codeigniter4/CodeIgniter4/blob/develop/system/HTTP/IncomingRequest.php#L99
/**
* Sets the locale string for this request.
*
* @param string $locale
*
* @return IncomingRequest
*/
public function setLocale(string $locale)
{
// If it's not a valid locale, set it
// to the default locale for the site.
if (! in_array($locale, $this->config->supportedLocales))
{
$locale = $this->defaultLocale;
}
$this->locale = $locale;
// If the intl extension is loaded, make sure
// that we set the locale for it... if not, though,
// don't worry about it.
// this should not block code coverage thru unit testing
// @codeCoverageIgnoreStart
try
{
if (class_exists('\Locale', false))
{
\Locale::setDefault($locale);
}
}
catch (\Exception $e)
{
}
// @codeCoverageIgnoreEnd
return $this;
}For reference my MainFilter class
<?php namespace Modules\Core\Base\Filters;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\Filters\FilterInterface;
use Config\App;
use Config\Database;
class MainFilter implements FilterInterface
{
/**
* Do whatever processing this filter needs to do.
* By default it should not return anything during
* normal execution. However, when an abnormal state
* is found, it should return an instance of
* CodeIgniter\HTTP\Response. If it does, script
* execution will end and that Response will be
* sent back to the client, allowing for error pages,
* redirects, etc.
*
* @param \CodeIgniter\HTTP\RequestInterface $request
*
* @param null $arguments
* @return mixed
*/
public function before(RequestInterface $request, $arguments = null)
{
$locales = [];
// get all languages from database
$db = Database::connect();
$results = $db->table('core_languages')
->select('language')
->where('published', 1)
->get()
->getResultArray();
if (!empty($results)) {
foreach ($results as $result) {
$locales[] = $result['language'];
}
}
if (!empty($locales)) {
/** @var App $config */
$config = Config('App');
$config->supportedLocales = $locales;
$request->config = $config;
$locale = $request->uri->getSegment(1);
if (in_array($locale, $locales)) {
$request->setLocale($locale);
} else {
$request->setLocale($config->defaultLocale);
}
}
}
//--------------------------------------------------------------------
/**
* Allows After filters to inspect and modify the response
* object as needed. This method does not allow any way
* to stop execution of other after filters, short of
* throwing an Exception or Error.
*
* @param \CodeIgniter\HTTP\RequestInterface $request
* @param \CodeIgniter\HTTP\ResponseInterface $response
*
* @param null $arguments
* @return mixed
*/
public function after(RequestInterface $request, ResponseInterface $response, $arguments = null)
{
}
//--------------------------------------------------------------------
}Context
- OS: Ubuntu 20.04 LTS
- Web server: Apache 2.4.41
- PHP version 7.4 and 8.0
My suggestion
I vote for solution 2 my-self and i can create a PR if needed after discussion and decision
Metadata
Metadata
Assignees
Labels
bugVerified issues on the current code behavior or pull requests that will fix themVerified issues on the current code behavior or pull requests that will fix them