How to automatically insert new translation into database in Yii 2 - php

I just started using Yii 2 and already running into some issues I can't figure out myself.
I set up the translator, to use my DB instead of files like this ( and two tables message and source_message):
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\DbMessageSource',
//'basePath' => '#app/messages',
//'sourceLanguage' => 'en',
],
],
],
I even set the translator parameter to true:
public $forceTranslation = true;
Now I create the text to translate like this:
<?=Yii::t('app', 'Congratulations!');?>
When I check the debug info, I see, that there has been only one query:
SELECT
"t1"."message" AS "message",
"t2"."translation" AS "translation"
FROM
"source_message" "t1",
"message" "t2"
WHERE
t1.id = t2.id AND
t1.category = 'app' AND
t2.language = 'en'
This doesn’t return anything, since there are no translations present. Now, what I can't figure out, how to make the system auto-create a new translation, for the missing translations.
Is such a feature already built in or do I need to create one my self? Because I couldn't find anything on the internet.
And, if there is not, what is the right way to do so?

I found this script by Aleksandr Zelenin that did exactly, what I needed: https://github.com/zelenin/yii2-i18n-module
Component uses yii\i18n\MissingTranslationEvent for auto-add of missing translations to database

Related

Yii2 framework: How to change English default language to Spanish

I am using the Yii2 Framework and I am translating all texts of buttons, labels, messages, etc.
Then I read this article http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html that shows how to do it automatically but I don't understand it.
I want to translate to Spanish from Argentina: es-AR or at least to any Spanish.
So I think I need to change from en-US to es-AR but I would like to know which files should I change.
Also I am using the great Gii code generator where I can see a checkbox called Enable I18N.
I watched these files but I am not sure if I am looking the right files:
vendor/yiisoft/yii2/base/Application.php
vendor/yiisoft/yii2/i18n/I18N.php
common/config/main-local.php
Add language propery and i18n component in application config. For advanced application template in common/config/main.php
return [
'language' => 'es-AR',
...
'components' => [
...
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
],
],
],
...
],
]
Use Yii::t() for all user messages (model labels, views, error messages etc).
echo \Yii::t('app', 'Friend');
Create directory messages/es-AR. Create file app.php in this directory and add translations
return [
'Friend' => 'Amigo',
'Girl' => 'Сhica',
...
];
Try to look into the official documentation, it is best tutorial for you. http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html
Also, look at this answer yii2 basic multiple language
You can change default language by changing 'language' parameter of your main configuration file. Like this:
return
[
// set target language to be English
'language' => 'en-US',
]
Where instead 'en-US' you must to set needed locale code, e.g. 'es-AR'

How i can get log message with yii2

i have a little problem.
I'm developing a php application using Yii2 framework and i want to save a log messagges into db table.
I'm coding my own component witch extends DbTarget, in this component i rewrite export() function to save data into my table. It's works fine, but i can't get the log message.
For example, when i call Yii:log('message log'), all my data are saved in my db except 'message log' because i don't know how to get this value in my component.
Any solutions?
thanks
P.s. I'm newbee with yii2 and i have read the official documentation, but i didn't find any solution.
It seems you should specify level of the message
Yii:log('message log', Logger::LEVEL_TRACE);
or use shortcut methods
Yii::info('message log');
Yii::trace('message log');
Yii::error('message log');
Check your config for another targets. May be your message goes to level or category of another target. Notice that default category is 'application'.
To be shure you can make this configuration
'components' => [
'log' => [
'targets' => [
[
'class' => 'YourDbTarget',
'levels' => ['info'],
'categories' => ['application'],
],
],
],
],
And try to log info message
Yii::info('message log'); // target = info, category = application

Yii2 logger not exporting messages from log targets

I'm tightening up the logging for our Yii2 application and are struggling with getting the Logger to actually write messages to a log file when dealing with specific categories.
Our project consists of the following Yii2 'Applications' : console, common, frontend, backend and the logging for each of these components work fine for Exceptions generated by Yii and general PHP Exceptions. However when I add some info messages for a specific category in the console part (which I execute by running commands via SHH) the directory that the file should be in is created but the file itself is not. I see that the newly specified log messages are inside the correct 'FileTarget' when I do a var_dump of it.
I've set the flushInterval of the 'log' component to 1 and the exportInterval of the logTarget to 1 to make sure that the messages are to be written to the targets directly. I'm aware that this should be set to a larger value at some point, but for now I want to make sure that the logs are actually being saved. Changing the interval values doesn't seem to have any effect.
A workaround I came up with is to manually call target->export() for the specific FileTarget. This is how I currently make sure logs are being written:
In the Controller where I want to log message I do
Yii::info('Report created succesfully.', 'reports-create');
UtilitiesController::forceLogExport('reports-create');
The forceLogExport method does this:
public function forceLogExport($categoryName = ''){
$logger = \Yii::getLogger();
foreach($logger->dispatcher->targets as $target){
if(!empty($categoryName)){
foreach($target->categories as $category){
if($category == $categoryName){
$target->export();
}
}
}
}
$logger->flush(true);
}
This does actually write the logs to the .log file, however there seem to be duplicate entries in the log now and it feels just plain wrong to call an export after every message.
As I read in the docs the actual writing of logs only happens when either these intervals are met OR when the application ends. I could imagine the application not ending properly so I tried forcing this by calling Yii:$app->end() directly after logging the message, but the file stays empty.
Since the problem is neither the application not ending (I can see that it does end) nor the interval being met (I see at least one message in the target and the interval is set to 1) I'm kind of at my wit's end why the logs are not exported. If anyone could perhaps elaborate any further on when/where Yii calls the ->export() method itself that would be a big help.
EDIT: added the console/config/main.php settings. Slightly changed my story, initially I wrote that 'the log file was being created but the messages were not being written in it.' but in fact only the directory that should contain the files was created, not the log file itself.
<?php
return [
'id' => 'console',
'basePath' => dirname(__DIR__),
'bootstrap' => ['log'],
'controllerNamespace' => 'console\controllers',
'components' => [
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'app\models\User',
//'enableAutoLogin' => true,
],
'session' => [ // for use session in console application
'class' => 'yii\web\Session'
],
'log' => [
'flushInterval' => 1,
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error','info', 'warning'],
'categories' => ['reports-schedule'],
'exportInterval' => 1,
'logVars' => [null],
'logFile' => '#app/../logs/console/'. date('Y') . '/' . date('m') . '/reports-schedule/' . 'reports-schedule_' . date('d-m-Y') . '.log'
],
[
'class' => 'yii\log\FileTarget',
'levels' => ['error','info', 'warning'],
'categories' => ['reports-create'],
'exportInterval' => 1,
'logVars' => [null],
'logFile' => '#app/../logs/console/'. date('Y') . '/' . date('m') . '/reports-create/' . 'reports-create_' . date('d-m-Y') . '.log'
],
// and 6 other similarly structured targets
[...],
[...],
[...],
[...],
[...],
[...],
],
]
];
UPDATE: it seems like I'll have to stick to manually calling ->export() on the desired log target. The problem I had with duplicate log entries (same message, same timestamp) being written was due to the fact that I had set the exportInterval property to 1 for the target (which I initially did to make sure the messages were exported at all). I suppose the logger stores messages until the value of exportInterval is met and then expect those messages to be written to the targets. I fixed duplicate entries from being written by removed the exportInterval property so Yii takes the default value (1000). For my case this would be sufficient since I wouldn't run into those numbers but for anyone reading this please consider your use case and check if you would run into anything close to that in a single cycle.
I had a similar issue at some point and I think this should be sufficient enough for your case.
Yii::$app->log->targets['reports-schedule']->logFile = $logPath;
Yii::info($message, $category);
Yii::getLogger()->flush();
This way you can specify a dynamic log path inside your schedule target and after flush the logger continues as it should.

Yii 2 multitranslation

How to enable multitranslation in yii 2 basic framework? I have tried, but it is not working. I get no error, but translation is not showing. Code:
public function actionLang(){
$lang = \Yii::$app->request->get('lang');
if($lang && in_array($lang,['en-US','ar-SA'])){
$cookie = new Cookie();
$cookie->name = '_lang';
$cookie->value = $lang;
$cookie->expire = time() + 60 * 60 * 24 * 180;
\Yii::$app->response->cookies->add($cookie);
}
$this->redirect(['index']);
}
I'm using this function in SiteController.
Internationalization in Yii is not a one-action job. Here's the documentation on how to make your website multilingual:
https://github.com/yiisoft/yii2/blob/master/docs/guide/tutorial-i18n.md
If docs are unclear, here is a tutorial:
http://code.tutsplus.com/tutorials/programming-with-yii2-localization-with-i18n--cms-23140
If you have gone through all the steps and merely wish to set the current language, you can use:
\Yii::$app->language = 'xxx';
where xxx is a language code in accordance with ISO 639-2.
Here are the mentioned standard's entries:
http://www.loc.gov/standards/iso639-2/php/code_list.php
First of all, from what I have gathered, you are trying to identify a language requested from the current request by doing $lang = \Yii::$app->request->get('lang'); and then set it in the cookie. In my opinion, this should be used as a "helper", meaning, it is useful to know the language preference of the returning client, but you still have to manage languages via URL, i.e. http://yoursite.com/en or http://yoursite.com/de should serve different languages.
Now, there are actually very good plugins out there for multilingual URL management, such as yii2-localeurls , which you can find here. I use it in production in multiple projects and highly recommend it.
To actually manage translations, you have to have a folder in the root of your project (if you are using advance template, you should have it inside frontend/backend/console ) to store the actual block translations, call it messages .
Now, under #app/messages create folders for each non-default language, for example #app/messages/de for German translations.
If you go your config in #app/config/main.php, look for i18n key inside the components array. If you can't find such a key, simply put the following into the components array:
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
'sourceLanguage' => 'en',
'fileMap' => [
'app' => 'app.php',
'app/error' => 'error.php',
],
],
'*' => [
'class' => 'yii\i18n\PhpMessageSource',
]
],
],
Now, you will need to create a translation file inside the relevant directory. In the above configuration, we declared that the default language used is en, that means that all original messages would be in English. Go to #app/messages/de and create a translations file inside that directory. You can call it whatever you like, but for this example, call it site.php.
In this site.php put the following:
return [
'Translate this!' => 'Your relevant translation here in whichever language',
'Translate this also!!!' => 'Stuff...'
];
If all done correctly, when you access your page via http://yousite.com/de, when using Yii::t('site', 'Translate this!') you should be getting 'Your relevant translation here in whichever language' instead.
The beauty of Yii 2 is that it is extremely well documented. Visit the official documentation if you are stuck, it really explains everything quite well.

how to setup multiple language in yii2 in simple way

I am working on yii2 framework.This is new framework for me. I want to setup multiple language. I tried some way but didn't got success. Can anyone please suggest me simplest way ? What should i have to do ?
I am using this reference link
http://techisworld.com/working-with-multiple-languages-app-in-yii2-framework-using-i18n-system.html
1- For dynamic content (coming from database) I usually use this:
webvimark/multilanguage
It is very easy and isolated from your app DB tables structure and code, that gives flexibility in adding/removing languages at the long term.
2- For static content (words inside the markup) in frontend as an example:
add the lines in your frontend/config/main.php file,
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '#app/messages',
'sourceLanguage' => 'en_US',
'fileMap' => [
'app' => 'app.php'
],
],
],
],
Put you translation file app.php file inside /frontend/messages, as any Yii translation file it returns an array of translations in a key-value pairs.
Then you can translate your static content using:
Yii::t('app', 'text to be translated')

Categories