Closed andreCatita closed 9 years ago
Hi @andreCatita
My code
public function testCreate()
{
$post = Post::find()->localized('en')->where(['id' => 4])->one();
$this->printInfo($post);
$post = Post::find()->localized('ru')->where(['id' => 4])->one();
$this->printInfo($post);
$post = Post::find()->where(['id' => 4])->asArray()->one();
echo $post['title'];
}
protected function printInfo($post)
{
echo "The language is " . Yii::$app->language . "\n";
echo "Title is " . $post->title . "\n";
}
Schema
DROP TABLE IF EXISTS "post";
CREATE TABLE "post" (
"id" INTEGER NOT NULL PRIMARY KEY,
"title" TEXT,
"body" TEXT
);
DROP TABLE IF EXISTS "postLang";
CREATE TABLE "postLang" (
"id" INTEGER NOT NULL PRIMARY KEY,
"post_id" INTEGER NOT NULL,
"language" varchar(6) NOT NULL,
"title" TEXT,
"body" TEXT
);
Data
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<post id="1"/>
<post id="2"/>
<post id="3"/>
<post id="4" title="No translation" body="No translation"/>
<postLang id="1" post_id="1" language="ru" title="Post title 1 ru" body="Post body 1 ru"/>
<postLang id="2" post_id="1" language="en" title="Post title 1 en" body="Post body 1 en"/>
<postLang id="3" post_id="2" language="ru" title="Post title 2 ru" body="Post body 2 ru"/>
<postLang id="4" post_id="2" language="en" title="Post title 2 en" body="Post body 2 en"/>
<postLang id="5" post_id="3" language="ru" title="Post title 3 ru" body="Post body 3 ru"/>
<postLang id="6" post_id="3" language="en" title="Post title 3 en" body="Post body 3 en"/>
<postLang id="7" post_id="4" language="ru" title="Post title 4 ru" body="Post body 4 ru"/>
<postLang id="8" post_id="4" language="en" title="Post title 4 en" body="Post body 4 en"/>
</dataset>
Output
The language is en-US
Title is Post title 4 en
The language is en-US
Title is Post title 4 ru
No translation
@andreCatita In 2.0 version column dublication is used just for fallback (if translation is empty)
Thanks @OmgDef
I figured what the problem is, I had a misconception about a variable, and now I don't know how to make this exception.
My exception was to not go to postLang table, if we are in my "defualtLanguage" (as I defined in params).
So in the MultilingualBehavior -> afterFind(), I have the following:
public function afterFind() {
....
if ($owner->isRelationPopulated('translations') && $related = $owner->getRelatedRecords()['translations']) {
...
...
} else {
// I HAVE THIS LINE HERE
if ($this->getCurrentLanguage() != \Yii::$app->params['defaultLanguage']) {
...
}
}
I assumed this->getCurrentLanguage() when using:
$post = Post::find()->localized('ru')->where(['id' => 4])->one();
would return 'ru', but apparently it always returns the \Yii::$app->language
How can I make this exception, that is to avoid going to the postLang table for the defaultLanguage?
Thanks
@andreCatita In case currentLanguage
property should be public. I think i can do it for you.
Problem is here https://github.com/OmgDef/yii2-multilingual-behavior/blob/master/src/MultilingualBehavior.php#L137
But I have no idea when you will assign a value to it. Model and behavior don't know anything about Query scopes.
@OmgDef Not sure I understood
Isn't there any way to retrieve the language filter that was applied in localized in afterFind? Meaning, get localized('ru') -> retrieve ru in afterFind? Or could we perhaps somehow define it so we can access it inside localized in MultilingualTrait ?
Thanks.
@andreCatita I think something like this
class Post extends \yii\db\ActiveRecord
{
protected static $currentLanguage;
public static function findLocalized($language)
{
static::$currentLanguage = $language;
return static::find()->localized($language);
}
/**
* @inheritdoc
*/
public static function tableName()
{
return 'post';
}
/**
* @inheritdoc
*/
public function behaviors()
{
return [
'ml' => [
'class' => MultilingualBehavior::className(),
'languages' => [
'ru' => 'Russian',
'en-US' => 'English',
],
'defaultLanguage' => 'ru',
'langForeignKey' => 'post_id',
'currentLanguage' => static::$currentLanguage,
'tableName' => "{{%postLang}}",
'attributes' => [
'title', 'body',
]
],
];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['title', 'body'], 'required'],
['title', 'string'],
];
}
/**
* @inheritdoc
*/
public function transactions()
{
return [
self::SCENARIO_DEFAULT => self::OP_ALL,
];
}
/**
* @inheritdoc
*/
public static function find()
{
return new MultilingualQuery(get_called_class());
}
/**
* @inheritdoc
*/
public function afterFind()
{
parent::afterFind();
static::$currentLanguage = null;
}
}
Yeah I thought something like that.. But I don't really like it.. I'll sleep on this, for later..
Hello @OmgDef
This is my first issue to you, that I have little info to give you.. But I'm going to explain what I think it might be:
-> localized('ru') worked in version 1.0.
So my team and I implemented your multilingual in a now almost production project. I told you in another bug I reported, that I'm still using the two tables with repeated columns, because like I said, when you changed that we decided it was too late for this project.
Still, I adapted your version 2.0 for other bugs, to support properly the two table system without repeating unnecessary queries. (Basically added an IF, to not query "postLang" for the "default" language)
But we haven't been using localized, and now that I tried it always returns me the values from the 'left' table.
I thought it would be because I have title in both "post" and "postLang" table still, but version 1.0 worked in that system, and from what I could tell, localized works the same way.
I thought it could be that, but while typing this, I decided to remove the 'title' column from "post", and it returned empty now, so it didn't grab from postLang.
Seeing the DB Log from Yii2, the queries were performed successfully. So it's something after the find, and the filling of the columns.
How can I debug this further? You have any idea? I suppose localized is working fine for everyone else?
Thanks for any help.