Browse Source

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
AD7six 11 years ago
parent
commit
7472b01428

+ 17 - 10
src/Model/Behavior/TranslateBehavior.php

@@ -17,6 +17,7 @@ namespace Cake\Model\Behavior;
 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 @@ class TranslateBehavior extends Behavior {
 	public function beforeFind(Event $event, $query) {
 		$locale = $this->locale();
 
-		if (empty($locale)) {
+		if ($locale === $this->config('defaultLocale')) {
 			return;
 		}
 
@@ -170,7 +172,7 @@ class TranslateBehavior extends Behavior {
 
 		$this->_bundleTranslatedFields($entity);
 
-		if (!$locale) {
+		if ($locale === $this->config('defaultLocale')) {
 			return;
 		}
 
@@ -230,7 +232,7 @@ class TranslateBehavior extends Behavior {
  */
 	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 @@ class TranslateBehavior extends Behavior {
 	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;
 		});
 	}

+ 99 - 0
tests/TestCase/Model/Behavior/TranslateBehaviorTest.php

@@ -16,6 +16,7 @@ namespace Cake\Test\TestCase\Model\Behavior;
 
 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();
 	}
@@ -80,6 +82,103 @@ class TranslateBehaviorTest extends TestCase {
 	}
 
 /**
+ * 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
  *