Skip to content

Commit

Permalink
implement translation behavior default locale
Browse files Browse the repository at this point in the history
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 7472b01
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 10 deletions.
27 changes: 17 additions & 10 deletions src/Model/Behavior/TranslateBehavior.php
Expand Up @@ -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;
Expand Down Expand Up @@ -63,7 +64,8 @@ class TranslateBehavior extends Behavior {
'implementedFinders' => ['translations' => 'findTranslations'],
'implementedMethods' => ['locale' => 'locale'],
'fields' => [],
'translationTable' => 'i18n'
'translationTable' => 'i18n',
'defaultLocale' => 'en_US'
];

/**
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -170,7 +172,7 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) {

$this->_bundleTranslatedFields($entity);

if (!$locale) {
if ($locale === $this->config('defaultLocale')) {
return;
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
});
}
Expand Down
99 changes: 99 additions & 0 deletions tests/TestCase/Model/Behavior/TranslateBehaviorTest.php
Expand Up @@ -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;
Expand All @@ -39,6 +40,7 @@ class TranslateBehaviorTest extends TestCase {
];

public function tearDown() {
I18n::defaultLocale('en_US');
parent::tearDown();
TableRegistry::clear();
}
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 7472b01

Please sign in to comment.