Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,40 @@ This will check and decide based on the following factors (in that order):

(**Note:** Locale codes in the (leftmost) subdomain are case-insensitive, i.e. `da-dk` works as well, and you can leave out region or script names, i.e. merely `da` would be sufficient here.)

1. **Path prefix** with locale code (e.g. `http://www.example.com/pt-BR/welcome.html`)
2. **Path prefix** with locale code (e.g. `http://www.example.com/pt-BR/welcome.html`)

(**Note:** Locale codes in the path prefix are case-insensitive, i.e. `pt-br` works as well, and you can leave out region or script names, i.e. merely `pt` would be sufficient here.)

1. **Query string** with locale code
3. **Query string** with locale code
1. the `locale` parameter
1. the `language` parameter
1. the `lang` parameter
1. the `lc` parameter
1. **Session field** defined via `I18n#setSessionField` (e.g. `$i18n->setSessionField('locale');`)
1. **Cookie** defined via `I18n#setCookieName` (e.g. `$i18n->setCookieName('lc');`), with an optional lifetime defined via `I18n#setCookieLifetime` (e.g. `$i18n->setCookieLifetime(60 * 60 * 24);`), where a value of `null` means that the cookie is to expire at the end of the current browser session
1. **HTTP request header** `Accept-Language` (e.g. `en-US,en;q=0.5`)
4. **Session field** defined via `I18n#setSessionField` (e.g. `$i18n->setSessionField('locale');`)
5. **Cookie** defined via `I18n#setCookieName` (e.g. `$i18n->setCookieName('lc');`), with an optional lifetime defined via `I18n#setCookieLifetime` (e.g. `$i18n->setCookieLifetime(60 * 60 * 24);`), where a value of `null` means that the cookie is to expire at the end of the current browser session
6. **Cookie** configuration:

- Name: defined via `I18n#setCookieName` (e.g. `$i18n->setCookieName('lc');`)
- Lifetime: optional, defined via `I18n#setCookieLifetime` (e.g. `$i18n->setCookieLifetime(60 * 60 * 24);`). A value of `null` means the cookie will expire at the end of the current browser session.
- Path: set using `I18n#setCookiePath` (e.g. `$i18n->setCookiePath('/');`)
- Domain: set using `I18n#setCookieDomain` (e.g. `$i18n->setCookieDomain('.example.com');`)
- Secure flag: set using `I18n#setCookieSecure` (e.g. `$i18n->setCookieSecure(true);`)
- HttpOnly flag: set using `I18n#setCookieHttpOnly` (e.g. `$i18n->setCookieHttpOnly(true);`)
- SameSite attribute: set using `I18n#setCookieSameSite` (e.g. `$i18n->setCookieSameSite('Lax');`)

Example of full cookie configuration:

```php
$i18n->setCookieName('lc');
$i18n->setCookieLifetime(60 * 60 * 24); // 24 hours
$i18n->setCookiePath('/');
$i18n->setCookieDomain('.example.com');
$i18n->setCookieSecure(true);
$i18n->setCookieHttpOnly(true);
$i18n->setCookieSameSite('Lax');
```
This configuration allows for fine-grained control over the cookie used to store the user's language preference, enhancing security and compliance with modern web standards.
7. **HTTP request header** `Accept-Language` (e.g. `en-US,en;q=0.5`)

You will usually choose a single one of these options to store and transport your locale codes, with other factors (specifically the last one) as fallback options. The first three options (and the last one) may provide advantages in terms of search engine optimization (SEO) and caching.

Expand Down
105 changes: 100 additions & 5 deletions src/I18n.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@ final class I18n {
private $cookieName;
/** @var int|null the lifetime (in seconds) of the cookie to use for retrieving and storing the preferred locale */
private $cookieLifetime;
/** @var string the path of the cookie */
private $cookiePath = '/';
/** @var string the domain of the cookie */
private $cookieDomain = '';
/** @var bool force use secure mode for the cookie */
private $cookieSecure = false;
/** @var bool force use HTTP only for the cookie */
private $cookieHttpOnly = false;
private $cookieSameSite = 'Lax';

/**
* Attempts to set the locale automatically
Expand Down Expand Up @@ -157,11 +166,14 @@ public function setLocaleManually($code) {
\setcookie(
$this->cookieName,
$supportedLocale,
!empty($this->cookieLifetime) ? \time() + (int) $this->cookieLifetime : 0,
'/',
'',
false,
false
[
'expires' => !empty($this->cookieLifetime) ? \time() + (int) $this->cookieLifetime : 0,
'path' => $this->cookiePath,
'domain' => $this->cookieDomain,
'secure' => $this->cookieSecure,
'httponly' => $this->cookieHttpOnly,
'samesite' => $this->cookieSameSite
]
);
}
}
Expand Down Expand Up @@ -646,4 +658,87 @@ private static function makeDefaultDirectory() {
return __DIR__ . '/../../../../locale';
}

/**
* @return string
*/
public function getCookiePath()
{
return $this->cookiePath;
}

/**
* @param string $cookiePath
*/
public function setCookiePath($cookiePath)
{
$this->cookiePath = $cookiePath;
}

/**
* @return string
*/
public function getCookieDomain()
{
return $this->cookieDomain;
}

/**
* @param string $cookieDomain
*/
public function setCookieDomain($cookieDomain)
{
$this->cookieDomain = $cookieDomain;
}

/**
* @return bool
*/
public function isCookieSecure()
{
return $this->cookieSecure;
}

/**
* @param bool $cookieSecure
*/
public function setCookieSecure($cookieSecure)
{
$this->cookieSecure = $cookieSecure;
}

/**
* @return bool
*/
public function isCookieHttpOnly()
{
return $this->cookieHttpOnly;
}

/**
* @param bool $cookieHttpOnly
*/
public function setCookieHttpOnly($cookieHttpOnly)
{
$this->cookieHttpOnly = $cookieHttpOnly;
}

/**
* @return string
*/
public function getCookieSameSite()
{
return $this->cookieSameSite;
}

/**
* @param string $cookieSameSite
*/
public function setCookieSameSite($cookieSameSite)
{
$this->cookieSameSite = $cookieSameSite;
}




}