260 lines
6.3 KiB
PHP
260 lines
6.3 KiB
PHP
<?php namespace RainLab\Translate\Classes;
|
|
|
|
use App;
|
|
use Config;
|
|
use Schema;
|
|
use Session;
|
|
use Request;
|
|
use RainLab\Translate\Models\Locale;
|
|
|
|
/**
|
|
* Translator class
|
|
*
|
|
* @package rainlab\translate
|
|
* @author Alexey Bobkov, Samuel Georges
|
|
*/
|
|
class Translator
|
|
{
|
|
use \October\Rain\Support\Traits\Singleton;
|
|
|
|
const SESSION_LOCALE = 'rainlab.translate.locale';
|
|
|
|
const SESSION_CONFIGURED = 'rainlab.translate.configured';
|
|
|
|
/**
|
|
* @var string The locale to use on the front end.
|
|
*/
|
|
protected $activeLocale;
|
|
|
|
/**
|
|
* @var string The default locale if no active is set.
|
|
*/
|
|
protected $defaultLocale;
|
|
|
|
/**
|
|
* @var boolean Determine if translate plugin is configured and ready to be used.
|
|
*/
|
|
protected $isConfigured;
|
|
|
|
/**
|
|
* Initialize the singleton
|
|
* @return void
|
|
*/
|
|
public function init()
|
|
{
|
|
$this->defaultLocale = $this->isConfigured() ? array_get(Locale::getDefault(), 'code', 'en') : 'en';
|
|
$this->activeLocale = $this->defaultLocale;
|
|
}
|
|
|
|
/**
|
|
* Changes the locale in the application and optionally stores it in the session.
|
|
* @param string $locale Locale to use
|
|
* @param boolean $remember Set to false to not store in the session.
|
|
* @return boolean Returns true if the locale exists and is set.
|
|
*/
|
|
public function setLocale($locale, $remember = true)
|
|
{
|
|
if (!Locale::isValid($locale)) {
|
|
return false;
|
|
}
|
|
|
|
App::setLocale($locale);
|
|
|
|
$this->activeLocale = $locale;
|
|
|
|
if ($remember) {
|
|
$this->setSessionLocale($locale);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns the active locale set by this instance.
|
|
* @param boolean $fromSession Look in the session.
|
|
* @return string
|
|
*/
|
|
public function getLocale($fromSession = false)
|
|
{
|
|
if ($fromSession && ($locale = $this->getSessionLocale())) {
|
|
return $locale;
|
|
}
|
|
|
|
return $this->activeLocale;
|
|
}
|
|
|
|
/**
|
|
* Returns the default locale as set by the application.
|
|
* @return string
|
|
*/
|
|
public function getDefaultLocale()
|
|
{
|
|
return $this->defaultLocale;
|
|
}
|
|
|
|
/**
|
|
* Check if this plugin is installed and the database is available,
|
|
* stores the result in the session for efficiency.
|
|
* @return boolean
|
|
*/
|
|
public function isConfigured()
|
|
{
|
|
if ($this->isConfigured !== null) {
|
|
return $this->isConfigured;
|
|
}
|
|
|
|
if (Session::has(self::SESSION_CONFIGURED)) {
|
|
$result = true;
|
|
}
|
|
elseif (App::hasDatabase() && Schema::hasTable('rainlab_translate_locales')) {
|
|
Session::put(self::SESSION_CONFIGURED, true);
|
|
$result = true;
|
|
}
|
|
else {
|
|
$result = false;
|
|
}
|
|
|
|
return $this->isConfigured = $result;
|
|
}
|
|
|
|
//
|
|
// Request handling
|
|
//
|
|
|
|
/**
|
|
* handleLocaleRoute will check if the route contains a translated locale prefix (/en/)
|
|
* and return that locale to be registered with the router.
|
|
* @return string
|
|
*/
|
|
public function handleLocaleRoute()
|
|
{
|
|
if (Config::get('rainlab.translate::disableLocalePrefixRoutes', false)) {
|
|
return '';
|
|
}
|
|
|
|
if (App::runningInBackend()) {
|
|
return '';
|
|
}
|
|
|
|
if (!$this->isConfigured()) {
|
|
return '';
|
|
}
|
|
|
|
if (!$this->loadLocaleFromRequest()) {
|
|
return '';
|
|
}
|
|
|
|
$locale = $this->getLocale();
|
|
if (!$locale) {
|
|
return '';
|
|
}
|
|
|
|
return $locale;
|
|
}
|
|
|
|
/**
|
|
* Sets the locale based on the first URI segment.
|
|
* @return bool
|
|
*/
|
|
public function loadLocaleFromRequest()
|
|
{
|
|
$locale = Request::segment(1);
|
|
|
|
if (!Locale::isValid($locale)) {
|
|
return false;
|
|
}
|
|
|
|
$this->setLocale($locale);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns the current path prefixed with language code.
|
|
*
|
|
* @param string $locale optional language code, default to the system default language
|
|
* @return string
|
|
*/
|
|
public function getCurrentPathInLocale($locale = null)
|
|
{
|
|
return $this->getPathInLocale(Request::path(), $locale);
|
|
}
|
|
|
|
/**
|
|
* Returns the path prefixed with language code.
|
|
*
|
|
* @param string $path Path to rewrite, already translate, with or without locale prefixed
|
|
* @param string $locale optional language code, default to the system default language
|
|
* @param boolean $prefixDefaultLocale should we prefix the path when the locale = default locale
|
|
* @return string
|
|
*/
|
|
public function getPathInLocale($path, $locale = null, $prefixDefaultLocale = null)
|
|
{
|
|
$prefixDefaultLocale = (is_null($prefixDefaultLocale))
|
|
? Config::get('rainlab.translate::prefixDefaultLocale')
|
|
: $prefixDefaultLocale;
|
|
|
|
$segments = explode('/', $path);
|
|
|
|
$segments = array_values(array_filter($segments, function ($v) {
|
|
return $v != '';
|
|
}));
|
|
|
|
if (is_null($locale) || !Locale::isValid($locale)) {
|
|
$locale = $this->defaultLocale;
|
|
}
|
|
|
|
if (count($segments) == 0 || Locale::isValid($segments[0])) {
|
|
$segments[0] = $locale;
|
|
} else {
|
|
array_unshift($segments, $locale);
|
|
}
|
|
|
|
// If we don't want te default locale to be prefixed
|
|
// and the first segment equals the default locale
|
|
if (
|
|
!$prefixDefaultLocale &&
|
|
isset($segments[0]) &&
|
|
$segments[0] == $this->defaultLocale
|
|
) {
|
|
// Remove the default locale
|
|
array_shift($segments);
|
|
};
|
|
|
|
return htmlspecialchars(implode('/', $segments), ENT_QUOTES, 'UTF-8');
|
|
}
|
|
|
|
//
|
|
// Session handling
|
|
//
|
|
|
|
/**
|
|
* Looks at the session storage to find a locale.
|
|
* @return bool
|
|
*/
|
|
public function loadLocaleFromSession()
|
|
{
|
|
$locale = $this->getSessionLocale();
|
|
|
|
if (!$locale) {
|
|
return false;
|
|
}
|
|
|
|
$this->setLocale($locale);
|
|
return true;
|
|
}
|
|
|
|
protected function getSessionLocale()
|
|
{
|
|
if (!Session::has(self::SESSION_LOCALE)) {
|
|
return null;
|
|
}
|
|
|
|
return Session::get(self::SESSION_LOCALE);
|
|
}
|
|
|
|
protected function setSessionLocale($locale)
|
|
{
|
|
Session::put(self::SESSION_LOCALE, $locale);
|
|
}
|
|
}
|