Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implemented find('translations') to get a list of all translations for

each record
  • Loading branch information...
commit 4deb658f2473198e79802b0b06ef357c08881463 1 parent aa04995
@lorenzo lorenzo authored
View
67 src/Model/Behavior/TranslateBehavior.php
@@ -40,7 +40,7 @@ class TranslateBehavior extends Behavior {
* @var array
*/
protected static $_defaultConfig = [
- 'implementedFinders' => [],
+ 'implementedFinders' => ['translations' => 'findTranslations'],
'implementedMethods' => ['locale' => 'locale'],
'fields' => []
];
@@ -54,11 +54,13 @@ class TranslateBehavior extends Behavior {
public function __construct(Table $table, array $config = []) {
parent::__construct($table, $config);
$this->_table = $table;
+ $fields = $this->config()['fields'];
+ $this->setupFieldAssociations($fields);
}
- public function setupFieldAssociations() {
+ public function setupFieldAssociations($fields) {
$alias = $this->_table->alias();
- foreach ($this->config()['fields'] as $field) {
+ foreach ($fields as $field) {
$name = $field . '_translation';
$target = TableRegistry::get($name);
$target->table('i18n');
@@ -74,34 +76,35 @@ public function setupFieldAssociations() {
'propertyName' => $field . '_translation'
]);
}
+
+ $this->_table->hasMany('I18n', [
+ 'foreignKey' => 'foreign_key',
+ 'strategy' => 'subquery',
+ 'conditions' => ['I18n.model' => $alias],
+ 'propertyName' => '_i18n'
+ ]);
}
public function beforeFind(Event $event, $query) {
- $fields = $this->config()['fields'];
+ $locale = $this->locale();
- if (empty($fields)) {
+ if (empty($locale)) {
return;
}
- $locale = (array)$this->locale();
- if (!$locale || count($locale) > 1) {
- return;
- }
-
- $this->setupFieldAssociations();
$conditions = function($q) use ($locale) {
return $q
->select(['id', 'content'])
- ->where([$q->repository()->alias() . '.locale IN' => $locale]);
+ ->where([$q->repository()->alias() . '.locale' => $locale]);
};
$contain = [];
+ $fields = $this->config()['fields'];
foreach ($fields as $field) {
$contain[$field . '_translation'] = $conditions;
}
$query->contain($contain);
- $locale = current($locale);
$query->formatResults(function($results) use ($locale) {
return $this->_rowMapper($results, $locale);
}, $query::PREPEND);
@@ -111,7 +114,21 @@ public function locale($locale = null) {
if ($locale === null) {
return $this->_locale;
}
- return $this->_locale = $locale;
+ return $this->_locale = (string)$locale;
+ }
+
+ public function findTranslations($query, $options) {
+ $locales = isset($options['locales']) ? $options['locales'] : [];
+ return $query
+ ->contain(['I18n' => function($q) use ($locales) {
+ if ($locales) {
+ $q->where(['I18n.locale IN' => $locales]);
+ }
+ return $q;
+ }])
+ ->formatResults(function($results) {
+ return $this->_groupTranslations($results);
+ });
}
protected function _rowMapper($results, $locale) {
@@ -138,4 +155,26 @@ protected function _rowMapper($results, $locale) {
});
}
+ protected function _groupTranslations($results) {
+ return $results->map(function($row) {
+ $translations = (array)$row->get('_i18n');
+ $grouped = new Collection($translations);
+
+ $result = [];
+ foreach ($grouped->combine('field', 'content', 'locale') as $locale => $keys) {
+ $translation = new Entity($keys + ['locale' => $locale], [
+ 'markNew' => false,
+ 'useSetters' => false,
+ 'markClean' => true
+ ]);
+ $result[$locale] = $translation;
+ }
+
+ $options = ['setter' => false, 'guard' => false];
+ $row->set('_translations', $result, $options);
+ unset($row['_i18n']);
+ return $row;
+ });
+ }
+
}
View
43 tests/TestCase/Model/Behavior/TranslateBehaviorTest.php
@@ -35,6 +35,11 @@ class TranslateBehaviorTest extends TestCase {
'core.article'
];
+ public function tearDown() {
+ parent::tearDown();
+ TableRegistry::clear();
+ }
+
/**
* Tests that fields from a translated model are overriden
*
@@ -61,7 +66,6 @@ public function testFindSingleLocale() {
*/
public function testFindSingleLocaleWithConditions() {
$table = TableRegistry::get('Articles');
- $table->addBehavior('Translate');
$table->addBehavior('Translate', ['fields' => ['title', 'body']]);
$table->locale('eng');
$results = $table->find()
@@ -89,7 +93,6 @@ public function testFindSingleLocaleWithConditions() {
*/
public function testFindList() {
$table = TableRegistry::get('Articles');
- $table->addBehavior('Translate');
$table->addBehavior('Translate', ['fields' => ['title', 'body']]);
$table->locale('eng');
@@ -105,11 +108,45 @@ public function testFindList() {
*/
public function testFindCount() {
$table = TableRegistry::get('Articles');
- $table->addBehavior('Translate');
$table->addBehavior('Translate', ['fields' => ['title', 'body']]);
$table->locale('eng');
$this->assertEquals(3, $table->find()->count());
}
+
+ public function testFindTranslations() {
+ $table = TableRegistry::get('Articles');
+ $table->addBehavior('Translate', ['fields' => ['title', 'body']]);
+ $results = $table->find('translations');
+ $expected = [
+ [
+ 'eng' => ['title' => 'Title #1', 'body' => 'Content #1', 'locale' => 'eng'],
+ 'deu' => ['title' => 'Titel #1', 'body' => 'Inhalt #1', 'locale' => 'deu'],
+ 'cze' => ['title' => 'Titulek #1', 'body' => 'Obsah #1', 'locale' => 'cze']
+ ],
+ [
+ 'eng' => ['title' => 'Title #2', 'body' => 'Content #2', 'locale' => 'eng'],
+ 'deu' => ['title' => 'Titel #2', 'body' => 'Inhalt #2', 'locale' => 'deu'],
+ 'cze' => ['title' => 'Titulek #2', 'body' => 'Obsah #2', 'locale' => 'cze']
+ ],
+ [
+ 'eng' => ['title' => 'Title #3', 'body' => 'Content #3', 'locale' => 'eng'],
+ 'deu' => ['title' => 'Titel #3', 'body' => 'Inhalt #3', 'locale' => 'deu'],
+ 'cze' => ['title' => 'Titulek #3', 'body' => 'Obsah #3', 'locale' => 'cze']
+ ]
+ ];
+
+ $translations = $results->map(function($row) {
+ $translations = $row->get('_translations');
+ if (!$translations) {
+ return [];
+ }
+ return array_map(function($t) {
+ return $t->toArray();
+ }, $translations);
+ });
+ $this->assertEquals($expected, $translations->toArray());
+ }
+
}
Please sign in to comment.
Something went wrong with that request. Please try again.