diff --git a/src/ORM/Behavior/TranslateBehavior.php b/src/ORM/Behavior/TranslateBehavior.php index dd9d511452a..840aaf2ddb5 100644 --- a/src/ORM/Behavior/TranslateBehavior.php +++ b/src/ORM/Behavior/TranslateBehavior.php @@ -77,6 +77,8 @@ class TranslateBehavior extends Behavior implements PropertyMarshalInterface protected $_defaultConfig = [ 'implementedFinders' => ['translations' => 'findTranslations'], 'implementedMethods' => [ + 'setLocale' => 'setLocale', + 'getLocale' => 'getLocale', 'locale' => 'locale', 'translationField' => 'translationField' ], @@ -207,7 +209,7 @@ public function setupFieldAssociations($fields, $table, $model, $strategy) */ public function beforeFind(Event $event, Query $query, ArrayObject $options) { - $locale = $this->locale(); + $locale = $this->getLocale(); if ($locale === $this->getConfig('defaultLocale')) { return; @@ -271,7 +273,7 @@ public function beforeFind(Event $event, Query $query, ArrayObject $options) */ public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $options) { - $locale = $entity->get('_locale') ?: $this->locale(); + $locale = $entity->get('_locale') ?: $this->getLocale(); $newOptions = [$this->_translationTable->getAlias() => ['validate' => false]]; $options['associated'] = $newOptions + $options['associated']; @@ -412,21 +414,69 @@ public function buildMarshalMap($marshaller, $map, $options) ]; } + /** + * Sets the locale that should be used for all future find and save operations on + * the table where this behavior is attached to. + * + * When fetching records, the behavior will include the content for the locale set + * via this method, and likewise when saving data, it will save the data in that + * locale. + * + * Note that in case an entity has a `_locale` property set, that locale will win + * over the locale set via this method (and over the globally configured one for + * that matter)! + * + * @param string|null $locale The locale to use for fetching and saving records. Pass `null` + * in order to unset the current locale, and to make the behavior fall back to using the + * globally configured locale. + * @return $this + * @see \Cake\ORM\Behavior\TranslateBehavior::getLocale() + * @link https://book.cakephp.org/3.0/en/orm/behaviors/translate.html#retrieving-one-language-without-using-i18n-locale + * @link https://book.cakephp.org/3.0/en/orm/behaviors/translate.html#saving-in-another-language + */ + public function setLocale($locale) + { + $this->_locale = $locale; + + return $this; + } + + /** + * Returns the current locale. + * + * If no locale has been explicitly set via `setLocale()`, this method will return + * the currently configured global locale. + * + * @return string + * @see \Cake\I18n\I18n::getLocale() + * @see \Cake\ORM\Behavior\TranslateBehavior::setLocale() + */ + public function getLocale() + { + return $this->_locale ?: I18n::getLocale(); + } + /** * Sets all future finds for the bound table to also fetch translated fields for * the passed locale. If no value is passed, it returns the currently configured * locale * + * @deprecated 3.6.0 Use setLocale()/getLocale() instead. * @param string|null $locale The locale to use for fetching translated records * @return string */ public function locale($locale = null) { - if ($locale === null) { - return $this->_locale ?: I18n::getLocale(); + deprecationWarning( + get_called_class() . '::locale() is deprecated. ' . + 'Use setLocale()/getLocale() instead.' + ); + + if ($locale !== null) { + $this->setLocale($locale); } - return $this->_locale = (string)$locale; + return $this->getLocale(); } /** @@ -442,7 +492,7 @@ public function locale($locale = null) public function translationField($field) { $table = $this->_table; - if ($this->locale() === $this->getConfig('defaultLocale')) { + if ($this->getLocale() === $this->getConfig('defaultLocale')) { return $table->aliasField($field); } $associationName = $table->getAlias() . '_' . $field . '_translation'; diff --git a/tests/TestCase/ORM/Behavior/TranslateBehaviorTest.php b/tests/TestCase/ORM/Behavior/TranslateBehaviorTest.php index 6186cc10794..54e2ef62b21 100644 --- a/tests/TestCase/ORM/Behavior/TranslateBehaviorTest.php +++ b/tests/TestCase/ORM/Behavior/TranslateBehaviorTest.php @@ -130,7 +130,7 @@ public function testFindSingleLocale() { $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('eng'); + $table->setLocale('eng'); $results = $table->find()->combine('title', 'body', 'id')->toArray(); $expected = [ 1 => ['Title #1' => 'Content #1'], @@ -149,7 +149,7 @@ public function testFindTranslationsFormatResultsIteration() { $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('eng'); + $table->setLocale('eng'); $results = $table->find('translations') ->limit(1) ->formatResults(function ($results) { @@ -282,7 +282,7 @@ public function testFindSingleLocaleWithNullTranslation() { $table = $this->getTableLocator()->get('Comments'); $table->addBehavior('Translate', ['fields' => ['comment']]); - $table->locale('spa'); + $table->setLocale('spa'); $results = $table->find() ->where(['Comments.id' => 6]) ->combine('id', 'comment')->toArray(); @@ -300,7 +300,7 @@ public function testFindSingleLocaleWithgetConditions() { $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('eng'); + $table->setLocale('eng'); $results = $table->find() ->where(['Articles.id' => 2]) ->all(); @@ -319,6 +319,28 @@ public function testFindSingleLocaleWithgetConditions() $this->assertEquals($expected, $row->toArray()); } + /** + * Tests the locale setter/getter. + * + * @return void + */ + public function testSetGetLocale() + { + $table = $this->getTableLocator()->get('Articles'); + $table->addBehavior('Translate'); + + $this->assertEquals('en_US', $table->getLocale()); + + $table->setLocale('fr_FR'); + $this->assertEquals('fr_FR', $table->getLocale()); + + $table->setLocale(null); + $this->assertEquals('en_US', $table->getLocale()); + + I18n::setLocale('fr_FR'); + $this->assertEquals('fr_FR', $table->getLocale()); + } + /** * Tests translationField method for translated fields. * @@ -361,11 +383,11 @@ public function testTranslationFieldForTranslatedFields() $field = $table->translationField('title'); $this->assertSame($expectedOtherLocale, $field); - $table->locale('de_DE'); + $table->setLocale('de_DE'); $field = $table->translationField('title'); $this->assertSame($expectedSameLocale, $field); - $table->locale('es'); + $table->setLocale('es'); $field = $table->translationField('title'); $this->assertSame($expectedOtherLocale, $field); } @@ -394,7 +416,7 @@ public function testFindList() { $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('eng'); + $table->setLocale('eng'); $results = $table->find('list')->toArray(); $expected = [1 => 'Title #1', 2 => 'Title #2', 3 => 'Title #3']; @@ -410,7 +432,7 @@ public function testFindCount() { $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('eng'); + $table->setLocale('eng'); $this->assertEquals(3, $table->find()->count()); } @@ -528,7 +550,7 @@ public function testFindTranslationsWithFieldOverriding() { $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('cze'); + $table->setLocale('cze'); $results = $table->find('translations', ['locales' => ['deu', 'cze']]); $expected = [ [ @@ -571,8 +593,8 @@ public function testFindSingleLocaleHasMany() $comments = $table->hasMany('Comments')->getTarget(); $comments->addBehavior('Translate', ['fields' => ['comment']]); - $table->locale('eng'); - $comments->locale('eng'); + $table->setLocale('eng'); + $comments->setLocale('eng'); $results = $table->find()->contain(['Comments' => function ($q) { return $q->select(['id', 'comment', 'article_id']); @@ -642,8 +664,8 @@ public function testTranslationsHasManyWithOverride() $comments = $table->hasMany('Comments')->getTarget(); $comments->addBehavior('Translate', ['fields' => ['comment']]); - $table->locale('cze'); - $comments->locale('eng'); + $table->setLocale('cze'); + $comments->setLocale('eng'); $results = $table->find('translations')->contain([ 'Comments' => function ($q) { return $q->find('translations')->select(['id', 'comment', 'article_id']); @@ -694,8 +716,8 @@ public function testFindSingleLocaleBelongsto() $authors = $table->belongsTo('Authors')->getTarget(); $authors->addBehavior('Translate', ['fields' => ['name']]); - $table->locale('eng'); - $authors->locale('eng'); + $table->setLocale('eng'); + $authors->setLocale('eng'); $results = $table->find() ->select(['title', 'body']) @@ -744,7 +766,7 @@ public function testFindSingleLocaleBelongsToMany() $table->belongsToMany('Tags', [ 'through' => $specialTags ]); - $specialTags->locale('eng'); + $specialTags->setLocale('eng'); $result = $table->get(2, ['contain' => 'Tags']); $this->assertNotEmpty($result); @@ -761,7 +783,7 @@ public function testUpdateSingleLocale() { $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('eng'); + $table->setLocale('eng'); $article = $table->find()->first(); $this->assertEquals(1, $article->get('id')); $article->set('title', 'New translated article'); @@ -773,12 +795,12 @@ public function testUpdateSingleLocale() $this->assertEquals('New translated article', $article->get('title')); $this->assertEquals('Content #1', $article->get('body')); - $table->locale(false); + $table->setLocale(false); $article = $table->find()->first(); $this->assertEquals(1, $article->get('id')); $this->assertEquals('First Article', $article->get('title')); - $table->locale('eng'); + $table->setLocale('eng'); $article->set('title', 'Wow, such translated article'); $article->set('body', 'A translated body'); $table->save($article); @@ -799,7 +821,7 @@ public function testInsertNewTranslations() { $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('fra'); + $table->setLocale('fra'); $article = $table->find()->first(); $this->assertEquals(1, $article->get('id')); @@ -982,7 +1004,7 @@ public function testUpdateTranslationWithLocaleInEntity() $this->assertEquals('First Article', $article->get('title')); $this->assertEquals('First Article Body', $article->get('body')); - $table->locale('fra'); + $table->setLocale('fra'); $article = $table->find()->first(); $this->assertEquals(1, $article->get('id')); $this->assertEquals('Le titre', $article->get('title')); @@ -1000,7 +1022,7 @@ public function testSaveTranslationWithAssociationWhitelist() $table = $this->getTableLocator()->get('Articles'); $table->hasMany('Comments'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('fra'); + $table->setLocale('fra'); $article = $table->find()->first(); $this->assertEquals(1, $article->get('id')); @@ -1137,7 +1159,7 @@ public function testTranslationWithUnionQuery() { $table = $this->getTableLocator()->get('Comments'); $table->addBehavior('Translate', ['fields' => ['comment']]); - $table->locale('spa'); + $table->setLocale('spa'); $query = $table->find()->where(['Comments.id' => 6]); $query2 = $table->find()->where(['Comments.id' => 5]); $query->union($query2); @@ -1222,11 +1244,11 @@ public function testFilterUntranslated() 'fields' => ['title', 'body'], 'onlyTranslated' => true ]); - $table->locale('eng'); + $table->setLocale('eng'); $results = $table->find()->where(['Articles.id' => 1])->all(); $this->assertCount(1, $results); - $table->locale('fr'); + $table->setLocale('fr'); $results = $table->find()->where(['Articles.id' => 1])->all(); $this->assertCount(0, $results); } @@ -1245,19 +1267,19 @@ public function testFilterUntranslatedWithFinder() 'fields' => ['comment'], 'onlyTranslated' => true ]); - $table->locale('eng'); + $table->setLocale('eng'); $results = $table->find('translations')->all(); $this->assertCount(4, $results); - $table->locale('spa'); + $table->setLocale('spa'); $results = $table->find('translations')->all(); $this->assertCount(1, $results); - $table->locale('spa'); + $table->setLocale('spa'); $results = $table->find('translations', ['filterByCurrentLocale' => false])->all(); $this->assertCount(6, $results); - $table->locale('spa'); + $table->setLocale('spa'); $results = $table->find('translations')->all(); $this->assertCount(1, $results); } @@ -1274,7 +1296,7 @@ public function testEmptyTranslations() 'fields' => ['title', 'body', 'description'], 'allowEmptyTranslations' => false, ]); - $table->locale('spa'); + $table->setLocale('spa'); $result = $table->find()->first(); $this->assertNull($result->description); } diff --git a/tests/TestCase/ORM/QueryRegressionTest.php b/tests/TestCase/ORM/QueryRegressionTest.php index 245dde8f1f7..cc27f106260 100644 --- a/tests/TestCase/ORM/QueryRegressionTest.php +++ b/tests/TestCase/ORM/QueryRegressionTest.php @@ -590,7 +590,7 @@ public function testAssociationSubQueryNoOffset() $this->loadFixtures('Articles', 'Translates'); $table = $this->getTableLocator()->get('Articles'); $table->addBehavior('Translate', ['fields' => ['title', 'body']]); - $table->locale('eng'); + $table->setLocale('eng'); $query = $table->find('translations') ->order(['Articles.id' => 'ASC']) ->limit(10)