Skip to content

Commit

Permalink
TranslateBehavior, his first steps
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Jan 26, 2014
1 parent d90ea72 commit f5593ed
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 22 deletions.
1 change: 0 additions & 1 deletion src/Database/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,6 @@ public function from($tables = [], $overwrite = false) {
protected function _buildFromPart($parts, $generator) {
$select = ' FROM %s';
$normalized = [];
$driver = $this->connection()->driver();
$parts = $this->_stringifyExpressions($parts, $generator);
foreach ($parts as $k => $p) {
if (!is_numeric($k)) {
Expand Down
106 changes: 106 additions & 0 deletions src/Model/Behavior/TranslateBehavior.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Model\Behavior;

use Cake\Collection\Collection;
use Cake\Event\Event;
use Cake\ORM\Behavior;
use Cake\ORM\Entity;
use Cake\ORM\Table;

class TranslateBehavior extends Behavior {

/**
* Table instance
*
* @var \Cake\ORM\Table
*/
protected $_table;

protected $_locale;

/**
* Default config
*
* These are merged with user-provided config when the behavior is used.
*
* @var array
*/
protected static $_defaultConfig = [
'implementedFinders' => [],
'implementedMethods' => ['locale' => 'locale']
];

/**
* Constructor
*
* @param Table $table The table this behavior is attached to.
* @param array $config The config for this behavior.
*/
public function __construct(Table $table, array $config = []) {
parent::__construct($table, $config);
$this->_table = $table;

$table->hasMany('I18n', [
'strategy' => 'subquery',
'foreignKey' => 'foreign_key',
'conditions' => ['I18n.model' => $table->alias()],
'propertyName' => '_i18n'
]);
}

public function beforeFind(Event $event, $query) {
$locale = (array)$this->locale();
$query->contain(['I18n' => function($q) use ($locale) {
if ($locale) {
$q->where(['I18n.locale IN' => $locale]);
}

return $q;
}]);

if (count($locale) === 1) {
$locale = current($locale);
$query->formatResults(function($results) use ($locale) {
return $this->_rowMapper($results, $locale);
});
}
}

public function locale($locale = null) {
if ($locale === null) {
return $this->_locale;
}
return $this->_locale = $locale;
}

protected function _rowMapper($results, $locale) {
return $results->map(function($row) use ($locale) {
$translations = (array)$row->get('_i18n');
$options = ['setter' => false, 'guard' => false];

foreach ($translations as $field) {
$row->set([
$field->get('field') => $field->get('content'),
'_locale' => $locale
], $options);
}
$row->clean();

return $row;
});
}

}
5 changes: 2 additions & 3 deletions src/ORM/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -1041,7 +1041,6 @@ protected function _addContainments() {

foreach ($this->_resolveJoins($this->_table, $contain) as $options) {
$table = $options['instance']->target();
$alias = $table->alias();
$this->_addJoin($options['instance'], $options['config']);
foreach ($options['associations'] as $relation => $meta) {
if ($meta['instance'] && !$meta['canBeJoined']) {
Expand Down Expand Up @@ -1127,7 +1126,7 @@ protected function _addJoin($association, $options) {
*/
protected function _eagerLoad($statement) {
$keys = $this->_collectKeys($statement);
foreach ($this->_loadEagerly as $association => $meta) {
foreach ($this->_loadEagerly as $meta) {
$contain = $meta['associations'];
$alias = $meta['instance']->source()->alias();
$keys = isset($keys[$alias]) ? $keys[$alias] : null;
Expand All @@ -1150,7 +1149,7 @@ protected function _eagerLoad($statement) {
*/
protected function _collectKeys($statement) {
$collectKeys = [];
foreach ($this->_loadEagerly as $association => $meta) {
foreach ($this->_loadEagerly as $meta) {
$source = $meta['instance']->source();
if ($meta['instance']->requiresKeys($meta['config'])) {
$alias = $source->alias();
Expand Down
36 changes: 18 additions & 18 deletions tests/Fixture/TranslateFixture.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,23 @@ class TranslateFixture extends TestFixture {
* @var array
*/
public $records = array(
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1'),
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Obsah #1'),
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title #2'),
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Content #2'),
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titel #2'),
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Inhalt #2'),
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titulek #2'),
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 2, 'field' => 'content', 'content' => 'Obsah #2'),
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title #3'),
array('locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Content #3'),
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titel #3'),
array('locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Inhalt #3'),
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titulek #3'),
array('locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 3, 'field' => 'content', 'content' => 'Obsah #3')
array('locale' => 'eng', 'model' => 'Articles', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Title #1'),
array('locale' => 'eng', 'model' => 'Articles', 'foreign_key' => 1, 'field' => 'body', 'content' => 'Content #1'),
array('locale' => 'deu', 'model' => 'Articles', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
array('locale' => 'deu', 'model' => 'Articles', 'foreign_key' => 1, 'field' => 'body', 'content' => 'Inhalt #1'),
array('locale' => 'cze', 'model' => 'Articles', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1'),
array('locale' => 'cze', 'model' => 'Articles', 'foreign_key' => 1, 'field' => 'body', 'content' => 'Obsah #1'),
array('locale' => 'eng', 'model' => 'Articles', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Title #2'),
array('locale' => 'eng', 'model' => 'Articles', 'foreign_key' => 2, 'field' => 'body', 'content' => 'Content #2'),
array('locale' => 'deu', 'model' => 'Articles', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titel #2'),
array('locale' => 'deu', 'model' => 'Articles', 'foreign_key' => 2, 'field' => 'body', 'content' => 'Inhalt #2'),
array('locale' => 'cze', 'model' => 'Articles', 'foreign_key' => 2, 'field' => 'title', 'content' => 'Titulek #2'),
array('locale' => 'cze', 'model' => 'Articles', 'foreign_key' => 2, 'field' => 'body', 'content' => 'Obsah #2'),
array('locale' => 'eng', 'model' => 'Articles', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Title #3'),
array('locale' => 'eng', 'model' => 'Articles', 'foreign_key' => 3, 'field' => 'body', 'content' => 'Content #3'),
array('locale' => 'deu', 'model' => 'Articles', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titel #3'),
array('locale' => 'deu', 'model' => 'Articles', 'foreign_key' => 3, 'field' => 'body', 'content' => 'Inhalt #3'),
array('locale' => 'cze', 'model' => 'Articles', 'foreign_key' => 3, 'field' => 'title', 'content' => 'Titulek #3'),
array('locale' => 'cze', 'model' => 'Articles', 'foreign_key' => 3, 'field' => 'body', 'content' => 'Obsah #3')
);
}
57 changes: 57 additions & 0 deletions tests/TestCase/Model/Behavior/TranslateBehaviorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Test\TestCase\Model\Behavior;

use Cake\Event\Event;
use Cake\Model\Behavior\TranslateBehavior;
use Cake\ORM\Entity;
use Cake\ORM\TableRegistry;
use Cake\TestSuite\TestCase;

/**
* Translate behavior test case
*/
class TranslateBehaviorTest extends TestCase {

/**
* fixtures
*
* @var array
*/
public $fixtures = [
'core.translate',
'core.article'
];

/**
* Tests that fields from a translated model are overriden
*
* @return void
*/
public function testFindSingleLocale() {
$table = TableRegistry::get('Articles');
$table->addBehavior('Translate');
$table->locale('eng');
$results = $table->find()->combine('title', 'body', 'id')->toArray();
$expected = [
1 => ['Title #1' => 'Content #1'],
2 => ['Title #2' => 'Content #2'],
3 => ['Title #3' => 'Content #3'],
];
$this->assertSame($expected, $results);
}

}

0 comments on commit f5593ed

Please sign in to comment.