Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix the allowEmptyTranslations presistence bug
  • Loading branch information
Michael Hoffmann committed Mar 6, 2017
1 parent 607c15c commit 9aed820
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/ORM/Behavior/TranslateBehavior.php
Expand Up @@ -272,6 +272,43 @@ public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $o
$newOptions = [$this->_translationTable->getAlias() => ['validate' => false]];
$options['associated'] = $newOptions + $options['associated'];

// Check early if empty transaltions are present in the entity.
// If this is the case, unset them to prevent persistence.
// This only applies if $this->_config['allowEmptyTranslations'] is false
if ($this->_config['allowEmptyTranslations'] === false) {
$translations = (array)$entity->get('_translations');
if (!empty($translations)) {
foreach ($translations as $locale => &$translation) {
$fields = $translation->extract($this->_config['fields'], false);
foreach ($fields as $field => $value) {
if (empty($value)) {
unset($translation->{$field});
}
}

// Workaround to check the remaining properties
$arrayEntity = $entity->toArray();

// If now, the current locale property is empty,
// unset it completely.
if (empty($arrayEntity['_translations'][$locale])) {
unset($entity->get('_translations')[$locale]);
}
}

// Workaround to check the remaining properties
$arrayEntity = $entity->toArray();

// If now, the whole _translations property is empty,
// unset it completely and return
if (empty($arrayEntity['_translations'])) {
$entity->unsetProperty("_translations");

return;
}
}
}

$this->_bundleTranslatedFields($entity);
$bundled = $entity->get('_i18n') ?: [];
$noBundled = count($bundled) === 0;
Expand Down
127 changes: 127 additions & 0 deletions tests/TestCase/ORM/Behavior/TranslateBehaviorTest.php
Expand Up @@ -787,6 +787,133 @@ public function testInsertNewTranslations()
$this->assertEquals('Le contenu', $article->get('body'));
}

/**
* Tests adding new translation to a record
*
* @return void
*/
public function testAllowEmptyFalse()
{
$table = TableRegistry::get('Articles');
$table->addBehavior('Translate', ['fields' => ['title'], 'allowEmptyTranslations' => false]);

$article = $table->find()->first();
$this->assertEquals(1, $article->get('id'));

$article = $table->patchEntity($article, [
'_translations' => [
'fra' => [
'title' => ''
]
]
]);

$table->save($article);

// Remove the Behavior to unset the content != '' condition
$table->removeBehavior('Translate');

$noFra = $table->I18n->find()->where(['locale' => 'fra'])->first();
$this->assertEmpty($noFra);
}

/**
* Tests adding new translation to a record
*
* @return void
*/
public function testMixedAllowEmptyFalse()
{
$table = TableRegistry::get('Articles');
$table->addBehavior('Translate', ['fields' => ['title', 'body'], 'allowEmptyTranslations' => false]);

$article = $table->find()->first();
$this->assertEquals(1, $article->get('id'));

$article = $table->patchEntity($article, [
'_translations' => [
'fra' => [
'title' => '',
'body' => 'Bonjour'
]
]
]);

$table->save($article);

$fra = $table->I18n->find()
->where([
'locale' => 'fra',
'field' => 'body'
])
->first();
$this->assertSame('Bonjour', $fra->content);

// Remove the Behavior to unset the content != '' condition
$table->removeBehavior('Translate');

$noTitle = $table->I18n->find()
->where([
'locale' => 'fra',
'field' => 'title'
])
->first();
$this->assertEmpty($noTitle);
}

/**
* Tests adding new translation to a record
*
* @return void
*/
public function testMultipleAllowEmptyFalse()
{
$table = TableRegistry::get('Articles');
$table->addBehavior('Translate', ['fields' => ['title', 'body'], 'allowEmptyTranslations' => false]);

$article = $table->find()->first();
$this->assertEquals(1, $article->get('id'));

$article = $table->patchEntity($article, [
'_translations' => [
'fra' => [
'title' => '',
'body' => 'Bonjour'
],
'de' => [
'title' => 'Titel',
'body' => 'Hallo'
]
]
]);

$table->save($article);

$fra = $table->I18n->find()
->where([
'locale' => 'fra',
'field' => 'body'
])
->first();
$this->assertSame('Bonjour', $fra->content);

$deTitle = $table->I18n->find()
->where([
'locale' => 'de',
'field' => 'title'
])
->first();
$this->assertSame('Titel', $deTitle->content);

$deBody = $table->I18n->find()
->where([
'locale' => 'de',
'field' => 'body'
])
->first();
$this->assertSame('Hallo', $deBody->content);
}

/**
* Tests that it is possible to use the _locale property to specify the language
* to use for saving an entity
Expand Down

0 comments on commit 9aed820

Please sign in to comment.