"Closes #3940, adding inserting/updating of multiple translations at once.

Additional tests added for TranslateBehavior"

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@6428 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
phpnut 2008-02-02 21:14:13 +00:00
parent acfc38e57d
commit df805f0a66
2 changed files with 184 additions and 32 deletions

View file

@ -62,21 +62,29 @@ class TranslateBehavior extends ModelBehavior {
$this->settings[$model->alias] = array(); $this->settings[$model->alias] = array();
$this->runtime[$model->alias] = array('fields' => array()); $this->runtime[$model->alias] = array('fields' => array());
$this->translateModel($model); $this->translateModel($model);
return $this->bindTranslation($model, null, false); return $this->bindTranslation($model, $config, false);
}
/**
* Callback
*/
function cleanup(&$model) {
$this->unbindTranslation($model);
unset($this->settings[$model->alias]);
unset($this->runtime[$model->alias]);
} }
/** /**
* Callback * Callback
*/ */
function beforeFind(&$model, $query) { function beforeFind(&$model, $query) {
$locale = $this->_getLocale($model); $locale = $this->_getLocale($model);
if (empty($locale)) {
return $query;
}
$db =& ConnectionManager::getDataSource($model->useDbConfig); $db =& ConnectionManager::getDataSource($model->useDbConfig);
$tablePrefix = $db->config['prefix']; $tablePrefix = $db->config['prefix'];
$RuntimeModel =& $this->translateModel($model); $RuntimeModel =& $this->translateModel($model);
if (is_string($query['fields']) && 'COUNT(*) AS '.$db->name('count') == $query['fields']) { if (is_string($query['fields']) && 'COUNT(*) AS '.$db->name('count') == $query['fields']) {
if (empty($locale)) {
return $query;
}
$query['fields'] = 'COUNT(DISTINCT('.$db->name($model->alias).'.'.$db->name($model->primaryKey).')) ' . $db->alias . 'count'; $query['fields'] = 'COUNT(DISTINCT('.$db->name($model->alias).'.'.$db->name($model->primaryKey).')) ' . $db->alias . 'count';
$query['joins'][] = array( $query['joins'][] = array(
'type' => 'INNER', 'type' => 'INNER',
@ -89,9 +97,6 @@ class TranslateBehavior extends ModelBehavior {
return $query; return $query;
} }
if (empty($locale)) {
return $query;
}
$autoFields = false; $autoFields = false;
if (empty($query['fields'])) { if (empty($query['fields'])) {
@ -208,7 +213,7 @@ class TranslateBehavior extends ModelBehavior {
function beforeSave(&$model) { function beforeSave(&$model) {
$locale = $this->_getLocale($model); $locale = $this->_getLocale($model);
if (empty($locale) || is_array($locale)) { if (empty($locale)) {
return true; return true;
} }
$fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']); $fields = array_merge($this->settings[$model->alias], $this->runtime[$model->alias]['fields']);
@ -235,25 +240,32 @@ class TranslateBehavior extends ModelBehavior {
$locale = $this->_getLocale($model); $locale = $this->_getLocale($model);
$tempData = $this->runtime[$model->alias]['beforeSave']; $tempData = $this->runtime[$model->alias]['beforeSave'];
unset($this->runtime[$model->alias]['beforeSave']); unset($this->runtime[$model->alias]['beforeSave']);
$conditions = array('locale' => $locale, 'model' => $model->alias, 'foreign_key' => $model->id); $conditions = array('model' => $model->alias, 'foreign_key' => $model->id);
$RuntimeModel =& $this->translateModel($model); $RuntimeModel =& $this->translateModel($model);
if (empty($created)) { foreach ($tempData as $field => $value) {
$translations = $RuntimeModel->find('list', array('conditions' => array_merge($conditions, array($RuntimeModel->displayField => array_keys($tempData))))); unset($conditions['content']);
$conditions['field'] = $field;
if ($translations) { if (is_array($value)) {
foreach ($translations as $id => $field) { $conditions['locale'] = array_keys($value);
$RuntimeModel->create(); } else {
$RuntimeModel->save(array($RuntimeModel->alias => array('id' => $id, 'content' => $tempData[$field]))); $conditions['locale'] = $locale;
unset($tempData[$field]); if (is_array($locale)) {
$value = array($locale[0] => $value);
} else {
$value = array($locale => $value);
} }
} }
} $translations = $RuntimeModel->find('list', array('conditions' => $conditions, 'fields' => array($RuntimeModel->alias . '.locale', $RuntimeModel->alias . '.id')));
foreach ($value as $_locale => $_value) {
if (!empty($tempData)) { $RuntimeModel->create();
foreach ($tempData as $field => $value) { $conditions['locale'] = $_locale;
$RuntimeModel->create(array_merge($conditions, array($RuntimeModel->displayField => $field, 'content' => $value))); $conditions['content'] = $_value;
$RuntimeModel->save(); if (array_key_exists($_locale, $translations)) {
$RuntimeModel->save(array($RuntimeModel->alias => array_merge($conditions, array('id' => $translations[$_locale]))));
} else {
$RuntimeModel->save(array($RuntimeModel->alias => $conditions));
}
} }
} }
} }
@ -315,15 +327,11 @@ class TranslateBehavior extends ModelBehavior {
* fake field * fake field
* *
* @param object instance of model * @param object instance of model
* @param mixed string with field, or array(field1, field2=>AssocName, field3), or null for bind all original translations * @param mixed string with field or array(field1, field2=>AssocName, field3)
* @param boolean $reset * @param boolean $reset
* @return bool * @return bool
*/ */
function bindTranslation(&$model, $fields = null, $reset = true) { function bindTranslation(&$model, $fields, $reset = true) {
if (empty($fields)) {
return $this->bindTranslation($model, $model->actsAs['Translate'], $reset);
}
if (is_string($fields)) { if (is_string($fields)) {
$fields = array($fields); $fields = array($fields);
} }
@ -395,7 +403,7 @@ class TranslateBehavior extends ModelBehavior {
*/ */
function unbindTranslation(&$model, $fields = null) { function unbindTranslation(&$model, $fields = null) {
if (empty($fields)) { if (empty($fields)) {
return $this->unbindTranslation($model, $model->actsAs['Translate']); return $this->unbindTranslation($model, $this->settings[$model->alias]);
} }
if (is_string($fields)) { if (is_string($fields)) {

View file

@ -77,7 +77,6 @@ class TranslateTest extends CakeTestCase {
var $Model = null; var $Model = null;
function startCase() { function startCase() {
$this->db->fullDebug = true;
$this->Model =& new TranslatedItem(); $this->Model =& new TranslatedItem();
$this->I18nModel =& ClassRegistry::getObject('TranslateTestModel'); $this->I18nModel =& ClassRegistry::getObject('TranslateTestModel');
} }
@ -136,7 +135,7 @@ class TranslateTest extends CakeTestCase {
unset($this->Model->hasMany['Title']['conditions']['locale']); unset($this->Model->hasMany['Title']['conditions']['locale']);
unset($this->Model->hasMany['Content']['conditions']['locale']); unset($this->Model->hasMany['Content']['conditions']['locale']);
$this->Model->unbindTranslation($translations); $this->Model->unbindTranslation($translations);
$this->Model->bindTranslation(null, false); $this->Model->bindTranslation(array('content', 'title'), false);
} }
function testLocaleSingle() { function testLocaleSingle() {
@ -320,6 +319,151 @@ class TranslateTest extends CakeTestCase {
$this->assertEqual($result, $expected); $this->assertEqual($result, $expected);
} }
function testMultipleCreate() {
$this->Model->locale = 'deu';
$data = array(
'slug' => 'new_translated',
'title' => array('eng' => 'New title', 'spa' => 'Nuevo leyenda'),
'content' => array('eng' => 'New content', 'spa' => 'Nuevo contenido')
);
$this->Model->create($data);
$this->Model->save();
$this->Model->unbindTranslation();
$translations = array('title' => 'Title', 'content' => 'Content');
$this->Model->bindTranslation($translations, false);
$this->Model->locale = array('eng', 'spa');
$result = $this->Model->read();
$expected = array(
'TranslatedItem' => array('id' => 4, 'slug' => 'new_translated', 'locale' => 'eng', 'title' => 'New title', 'content' => 'New content'),
'Title' => array(
array('id' => 19, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'title', 'content' => 'New title'),
array('id' => 20, 'locale' => 'spa', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'title', 'content' => 'Nuevo leyenda')
),
'Content' => array(
array('id' => 21, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'content', 'content' => 'New content'),
array('id' => 22, 'locale' => 'spa', 'model' => 'TranslatedItem', 'foreign_key' => 4, 'field' => 'content', 'content' => 'Nuevo contenido')
)
);
$this->assertEqual($result, $expected);
$this->Model->unbindTranslation($translations);
$this->Model->bindTranslation(array('title', 'content'), false);
}
function testMultipleUpdate() {
$this->Model->locale = 'eng';
$data = array('TranslatedItem' => array(
'id' => 1,
'title' => array('eng' => 'New Title #1', 'deu' => 'Neue Titel #1', 'cze' => 'Novy Titulek #1'),
'content' => array('eng' => 'New Content #1', 'deu' => 'Neue Inhalt #1', 'cze' => 'Novy Obsah #1')
));
$this->Model->create();
$this->Model->save($data);
$this->Model->unbindTranslation();
$translations = array('title' => 'Title', 'content' => 'Content');
$this->Model->bindTranslation($translations, false);
$result = $this->Model->read(null, 1);
$expected = array(
'TranslatedItem' => array('id' => '1', 'slug' => 'first_translated', 'locale' => 'eng', 'title' => 'New Title #1', 'content' => 'New Content #1'),
'Title' => array(
array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'New Title #1'),
array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Neue Titel #1'),
array('id' => 5, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Novy Titulek #1')
),
'Content' => array(
array('id' => 2, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'New Content #1'),
array('id' => 4, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Neue Inhalt #1'),
array('id' => 6, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Novy Obsah #1')
)
);
$this->assertEqual($result, $expected);
$this->Model->unbindTranslation($translations);
$this->Model->bindTranslation(array('title', 'content'), false);
}
function testMixedCreateUpdateWithArrayLocale() {
$this->Model->locale = array('cze', 'deu');
$data = array('TranslatedItem' => array(
'id' => 1,
'title' => array('eng' => 'Updated Title #1', 'spa' => 'Nuevo leyenda #1'),
'content' => 'Upraveny obsah #1'
));
$this->Model->create();
$this->Model->save($data);
$this->Model->unbindTranslation();
$translations = array('title' => 'Title', 'content' => 'Content');
$this->Model->bindTranslation($translations, false);
$result = $this->Model->read(null, 1);
$expected = array(
'TranslatedItem' => array('id' => 1, 'slug' => 'first_translated', 'locale' => 'cze', 'title' => 'Titulek #1', 'content' => 'Upraveny obsah #1'),
'Title' => array(
array('id' => 1, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Updated Title #1'),
array('id' => 3, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titel #1'),
array('id' => 5, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Titulek #1'),
array('id' => 19, 'locale' => 'spa', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'title', 'content' => 'Nuevo leyenda #1')
),
'Content' => array(
array('id' => 2, 'locale' => 'eng', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Content #1'),
array('id' => 4, 'locale' => 'deu', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Inhalt #1'),
array('id' => 6, 'locale' => 'cze', 'model' => 'TranslatedItem', 'foreign_key' => 1, 'field' => 'content', 'content' => 'Upraveny obsah #1')
)
);
$this->assertEqual($result, $expected);
$this->Model->unbindTranslation($translations);
$this->Model->bindTranslation(array('title', 'content'), false);
}
function testAttachDetach() {
$Behavior =& $this->Model->behaviors['Translate'];
$this->Model->unbindTranslation();
$translations = array('title' => 'Title', 'content' => 'Content');
$this->Model->bindTranslation($translations, false);
$result = array_keys($this->Model->hasMany);
$expected = array('Title', 'Content');
$this->assertEqual($result, $expected);
$this->Model->detach('Translate');
$result = array_keys($this->Model->hasMany);
$expected = array();
$this->assertEqual($result, $expected);
$result = isset($this->Model->behaviors['Translate']);
$this->assertFalse($result);
$result = isset($Behavior->settings[$this->Model->alias]);
$this->assertFalse($result);
$result = isset($Behavior->runtime[$this->Model->alias]);
$this->assertFalse($result);
$this->Model->attach('Translate', array('title' => 'Title', 'content' => 'Content'));
$result = array_keys($this->Model->hasMany);
$expected = array('Title', 'Content');
$this->assertEqual($result, $expected);
$result = isset($this->Model->behaviors['Translate']);
$this->assertTrue($result);
$result = isset($Behavior->settings[$this->Model->alias]);
$this->assertTrue($result);
$result = isset($Behavior->runtime[$this->Model->alias]);
$this->assertTrue($result);
$this->Model->unbindTranslation($translations);
$this->Model->bindTranslation(array('title', 'content'), false);
}
function testAnotherTranslateTable() { function testAnotherTranslateTable() {
$Model =& new TranslatedItemWithTable(); $Model =& new TranslatedItemWithTable();
$Model->locale = 'eng'; $Model->locale = 'eng';