Skip to content
Permalink
Browse files

implement translation behavior default locale

The behavior now reads I18n::defaultLocale() to find the locale to return
translations in unless explicitly overriden.

Bundled with this change set is adding support to the translate behavior
for unhydrated result sets

Fixes #4509
  • Loading branch information...
AD7six committed Sep 19, 2014
1 parent 4255491 commit 7472b01428c67ec873d096c992a02a4d42991b2a
Showing with 116 additions and 10 deletions.
  1. +17 −10 src/Model/Behavior/TranslateBehavior.php
  2. +99 −0 tests/TestCase/Model/Behavior/TranslateBehaviorTest.php
@@ -17,6 +17,7 @@
use ArrayObject;
use Cake\Collection\Collection;
use Cake\Event\Event;
use Cake\I18n\I18n;
use Cake\ORM\Behavior;
use Cake\ORM\Entity;
use Cake\ORM\Query;
@@ -63,7 +64,8 @@ class TranslateBehavior extends Behavior {
'implementedFinders' => ['translations' => 'findTranslations'],
'implementedMethods' => ['locale' => 'locale'],
'fields' => [],
'translationTable' => 'i18n'
'translationTable' => 'i18n',
'defaultLocale' => 'en_US'
];
/**
@@ -130,7 +132,7 @@ public function setupFieldAssociations($fields, $table) {
public function beforeFind(Event $event, $query) {
$locale = $this->locale();
if (empty($locale)) {
if ($locale === $this->config('defaultLocale')) {
return;
}
@@ -170,7 +172,7 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) {
$this->_bundleTranslatedFields($entity);
if (!$locale) {
if ($locale === $this->config('defaultLocale')) {
return;
}
@@ -230,7 +232,7 @@ public function afterSave(Event $event, Entity $entity) {
*/
public function locale($locale = null) {
if ($locale === null) {
return $this->_locale;
return $this->_locale ?: I18n::defaultLocale();
}
return $this->_locale = (string)$locale;
}
@@ -281,26 +283,31 @@ public function findTranslations(Query $query, array $options) {
protected function _rowMapper($results, $locale) {
return $results->map(function($row) use ($locale) {
$options = ['setter' => false, 'guard' => false];
$hydrated = !is_array($row);
foreach ($this->_config['fields'] as $field) {
$name = $field . '_translation';
$translation = $row->get($name);
$translation = isset($row[$name]) ? $row[$name] : null;
if ($translation === null || $translation === false) {
$row->unsetProperty($name);
unset($row[$name]);
continue;
}
$content = $translation->get('content');
$content = isset($translation['content']) ? $translation['content'] : null;
if ($content !== null) {
$row->set($field, $content, $options);
$row[$field] = $content;
}
unset($row[$name]);
}
$row->set('_locale', $locale, $options);
$row->clean();
$row['_locale'] = $locale;
if ($hydrated) {
$row->clean();
}
return $row;
});
}
@@ -16,6 +16,7 @@
use Cake\Collection\Collection;
use Cake\Event\Event;
use Cake\I18n\I18n;
use Cake\Model\Behavior\TranslateBehavior;
use Cake\ORM\Entity;
use Cake\ORM\TableRegistry;
@@ -39,6 +40,7 @@ class TranslateBehaviorTest extends TestCase {
];
public function tearDown() {
I18n::defaultLocale('en_US');
parent::tearDown();
TableRegistry::clear();
}
@@ -79,6 +81,103 @@ public function testFindSingleLocale() {
$this->assertSame($expected, $results);
}
/**
* Tests that fields from a translated model use the I18n class locale
* and that it propogates to associated models
*
* @return void
*/
public function testFindSingleLocaleAssociatedEnv() {
I18n::defaultLocale('eng');
$table = TableRegistry::get('Articles');
$table->addBehavior('Translate', ['fields' => ['title', 'body']]);
$table->hasMany('Comments');
$table->Comments->addBehavior('Translate', ['fields' => ['comment']]);
$results = $table->find()
->select(['id', 'title', 'body'])
->contain(['Comments' => ['fields' => ['article_id', 'comment']]])
->hydrate(false)
->toArray();
$expected = [
[
'id' => 1,
'title' => 'Title #1',
'body' => 'Content #1',
'comments' => [
['article_id' => 1, 'comment' => 'Comment #1', '_locale' => 'eng'],
['article_id' => 1, 'comment' => 'Comment #2', '_locale' => 'eng'],
['article_id' => 1, 'comment' => 'Comment #3', '_locale' => 'eng'],
['article_id' => 1, 'comment' => 'Comment #4', '_locale' => 'eng']
],
'_locale' => 'eng'
],
[
'id' => 2,
'title' => 'Title #2',
'body' => 'Content #2',
'comments' => [
['article_id' => 2, 'comment' => 'First Comment for Second Article', '_locale' => 'eng'],
['article_id' => 2, 'comment' => 'Second Comment for Second Article', '_locale' => 'eng']
],
'_locale' => 'eng'
],
[
'id' => 3,
'title' => 'Title #3',
'body' => 'Content #3',
'comments' => [],
'_locale' => 'eng'
]
];
$this->assertSame($expected, $results);
I18n::defaultLocale('spa');
$results = $table->find()
->select(['id', 'title', 'body'])
->contain(['Comments' => ['fields' => ['article_id', 'comment']]])
->hydrate(false)
->toArray();
$expected = [
[
'id' => 1,
'title' => 'First Article',
'body' => 'First Article Body',
'comments' => [
['article_id' => 1, 'comment' => 'First Comment for First Article', '_locale' => 'spa'],
['article_id' => 1, 'comment' => 'Second Comment for First Article', '_locale' => 'spa'],
['article_id' => 1, 'comment' => 'Third Comment for First Article', '_locale' => 'spa'],
['article_id' => 1, 'comment' => 'Comentario #4', '_locale' => 'spa']
],
'_locale' => 'spa'
],
[
'id' => 2,
'title' => 'Second Article',
'body' => 'Second Article Body',
'comments' => [
['article_id' => 2, 'comment' => 'First Comment for Second Article', '_locale' => 'spa'],
['article_id' => 2, 'comment' => 'Second Comment for Second Article', '_locale' => 'spa']
],
'_locale' => 'spa'
],
[
'id' => 3,
'title' => 'Third Article',
'body' => 'Third Article Body',
'comments' => [],
'_locale' => 'spa'
]
];
$this->assertSame($expected, $results);
}
/**
* Tests that fields from a translated model are not overriden if translation
* is null

0 comments on commit 7472b01

Please sign in to comment.
You can’t perform that action at this time.