Actually it is necessary to implement multilingualism both for the interface and for the database. So, when a user visits the site, it is necessary to determine the language of his browser and, depending on this, show the necessary translations.
I implemented this whole thing as follows:
I created a component and added it to the general application configuration:
'dbTranslator' => [ 'class' => 'common\components\DbTranslator', 'table' => 'lang' ],
Further, in the settings of the application I need, I called the component and redefined the language:
'on beforeRequest' => function ($event) { Yii::$app->dbTranslator->init(); Yii::$app->language = Yii::$app->dbTranslator->getLanguage('code'); },
The whole component looks like this:
<?php namespace common\components; use yii\base\InvalidConfigException; use yii\base\InvalidParamException; use yii\db\Query; use yii\helpers\ArrayHelper; use Yii; class DbTranslator { /** * Таблица где хранятся все доступные языки * @param string */ public $table = 'lang'; /** * Все поддерживаемые языки * @param array */ private $_supportLanguages; /** * Язык по умолчанию * @param array */ private $_defaultLanguage; /** * Инициализация компонента */ public function init() { $languages = (new Query) ->from($this->table) ->orderBy(['default' => SORT_DESC]) ->all(); if (!$languages) { throw new InvalidParamException('Languages NOT FOUND'); } if (!isset($languages[0]['default']) || $languages[0]['default'] != 1) { throw new InvalidParamException('Default language NOT FOUND'); } $this->_supportLanguages = ArrayHelper::index($languages, 'code'); $this->_defaultLanguage = $languages[0]; } /** * Определение языка на котором будет показан сайт * @return array|string */ public function getLanguage($item = false) { if (Yii::$app->session->get('user.language')) { $userLanguage = Yii::$app->session->get('user.language')['code']; } else if (isset(Yii::$app->request->cookies['language'])) { $userLanguage = Yii::$app->request->cookies->getValue('language'); } else { $userLanguage = $this->getUserLanguage(); } if (isset($this->_supportLanguages[$userLanguage])) { $language = $this->_supportLanguages[$userLanguage]; } else { $language = $this->_defaultLanguage; } if (!$item || !isset($language[$item])) { return $language; } return $language[$item]; } /** * Определение языка браузера пользователя * @return string */ public function getUserLanguage() { return substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); } /** * Язык системы по умолчанию * @return array */ public function getDefaultLanguage($item = false) { if (!$item || !isset($this->_defaultLanguage[$item])) { return $this->_defaultLanguage; } return $this->_defaultLanguage[$item]; } /** * Все поддерживаемые языки * @return array */ public function getLanguages() { return $this->_supportLanguages; } /** * Устанавливает выбранный язык */ public function setLanguage($lang) { if (isset($this->_supportLanguages[$lang])) { $language = $this->_supportLanguages[$lang]; } else { $language = $this->_defaultLanguage; } if (isset(Yii::$app->request->cookies['language'])) { Yii::$app->response->cookies->remove('language'); } Yii::$app->response->cookies->add(new \yii\web\Cookie([ 'name' => 'language', 'value' => $language['code'], 'expire' => time() + 86400 * 365, // Запись на 365 дней ])); Yii::$app->session->set('user.language', $language); } }
Actually everything works, no complaints. But there was some kind of back feeling that I could have done something wrong.
Please share tips and comments on this approach.
Update
And I just stay here: https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/tutorial-i18n.md
You probably did not understand me. The whole essence of the component is to determine the browser language, check whether it is supported by the site, if not, issue the default one and actually overwrite Yii::$app->language
.