Skip to content

Commit 9aed820

Browse files
author
Michael Hoffmann
committed
Fix the allowEmptyTranslations presistence bug
1 parent 607c15c commit 9aed820

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

src/ORM/Behavior/TranslateBehavior.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,43 @@ public function beforeSave(Event $event, EntityInterface $entity, ArrayObject $o
272272
$newOptions = [$this->_translationTable->getAlias() => ['validate' => false]];
273273
$options['associated'] = $newOptions + $options['associated'];
274274

275+
// Check early if empty transaltions are present in the entity.
276+
// If this is the case, unset them to prevent persistence.
277+
// This only applies if $this->_config['allowEmptyTranslations'] is false
278+
if ($this->_config['allowEmptyTranslations'] === false) {
279+
$translations = (array)$entity->get('_translations');
280+
if (!empty($translations)) {
281+
foreach ($translations as $locale => &$translation) {
282+
$fields = $translation->extract($this->_config['fields'], false);
283+
foreach ($fields as $field => $value) {
284+
if (empty($value)) {
285+
unset($translation->{$field});
286+
}
287+
}
288+
289+
// Workaround to check the remaining properties
290+
$arrayEntity = $entity->toArray();
291+
292+
// If now, the current locale property is empty,
293+
// unset it completely.
294+
if (empty($arrayEntity['_translations'][$locale])) {
295+
unset($entity->get('_translations')[$locale]);
296+
}
297+
}
298+
299+
// Workaround to check the remaining properties
300+
$arrayEntity = $entity->toArray();
301+
302+
// If now, the whole _translations property is empty,
303+
// unset it completely and return
304+
if (empty($arrayEntity['_translations'])) {
305+
$entity->unsetProperty("_translations");
306+
307+
return;
308+
}
309+
}
310+
}
311+
275312
$this->_bundleTranslatedFields($entity);
276313
$bundled = $entity->get('_i18n') ?: [];
277314
$noBundled = count($bundled) === 0;

tests/TestCase/ORM/Behavior/TranslateBehaviorTest.php

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,133 @@ public function testInsertNewTranslations()
787787
$this->assertEquals('Le contenu', $article->get('body'));
788788
}
789789

790+
/**
791+
* Tests adding new translation to a record
792+
*
793+
* @return void
794+
*/
795+
public function testAllowEmptyFalse()
796+
{
797+
$table = TableRegistry::get('Articles');
798+
$table->addBehavior('Translate', ['fields' => ['title'], 'allowEmptyTranslations' => false]);
799+
800+
$article = $table->find()->first();
801+
$this->assertEquals(1, $article->get('id'));
802+
803+
$article = $table->patchEntity($article, [
804+
'_translations' => [
805+
'fra' => [
806+
'title' => ''
807+
]
808+
]
809+
]);
810+
811+
$table->save($article);
812+
813+
// Remove the Behavior to unset the content != '' condition
814+
$table->removeBehavior('Translate');
815+
816+
$noFra = $table->I18n->find()->where(['locale' => 'fra'])->first();
817+
$this->assertEmpty($noFra);
818+
}
819+
820+
/**
821+
* Tests adding new translation to a record
822+
*
823+
* @return void
824+
*/
825+
public function testMixedAllowEmptyFalse()
826+
{
827+
$table = TableRegistry::get('Articles');
828+
$table->addBehavior('Translate', ['fields' => ['title', 'body'], 'allowEmptyTranslations' => false]);
829+
830+
$article = $table->find()->first();
831+
$this->assertEquals(1, $article->get('id'));
832+
833+
$article = $table->patchEntity($article, [
834+
'_translations' => [
835+
'fra' => [
836+
'title' => '',
837+
'body' => 'Bonjour'
838+
]
839+
]
840+
]);
841+
842+
$table->save($article);
843+
844+
$fra = $table->I18n->find()
845+
->where([
846+
'locale' => 'fra',
847+
'field' => 'body'
848+
])
849+
->first();
850+
$this->assertSame('Bonjour', $fra->content);
851+
852+
// Remove the Behavior to unset the content != '' condition
853+
$table->removeBehavior('Translate');
854+
855+
$noTitle = $table->I18n->find()
856+
->where([
857+
'locale' => 'fra',
858+
'field' => 'title'
859+
])
860+
->first();
861+
$this->assertEmpty($noTitle);
862+
}
863+
864+
/**
865+
* Tests adding new translation to a record
866+
*
867+
* @return void
868+
*/
869+
public function testMultipleAllowEmptyFalse()
870+
{
871+
$table = TableRegistry::get('Articles');
872+
$table->addBehavior('Translate', ['fields' => ['title', 'body'], 'allowEmptyTranslations' => false]);
873+
874+
$article = $table->find()->first();
875+
$this->assertEquals(1, $article->get('id'));
876+
877+
$article = $table->patchEntity($article, [
878+
'_translations' => [
879+
'fra' => [
880+
'title' => '',
881+
'body' => 'Bonjour'
882+
],
883+
'de' => [
884+
'title' => 'Titel',
885+
'body' => 'Hallo'
886+
]
887+
]
888+
]);
889+
890+
$table->save($article);
891+
892+
$fra = $table->I18n->find()
893+
->where([
894+
'locale' => 'fra',
895+
'field' => 'body'
896+
])
897+
->first();
898+
$this->assertSame('Bonjour', $fra->content);
899+
900+
$deTitle = $table->I18n->find()
901+
->where([
902+
'locale' => 'de',
903+
'field' => 'title'
904+
])
905+
->first();
906+
$this->assertSame('Titel', $deTitle->content);
907+
908+
$deBody = $table->I18n->find()
909+
->where([
910+
'locale' => 'de',
911+
'field' => 'body'
912+
])
913+
->first();
914+
$this->assertSame('Hallo', $deBody->content);
915+
}
916+
790917
/**
791918
* Tests that it is possible to use the _locale property to specify the language
792919
* to use for saving an entity

0 commit comments

Comments
 (0)