Skip to content

Commit

Permalink
Refactor empty field handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Hoffmann committed Mar 6, 2017
1 parent 9aed820 commit fbdb8bc
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 32 deletions.
69 changes: 37 additions & 32 deletions src/ORM/Behavior/TranslateBehavior.php
Expand Up @@ -272,41 +272,11 @@ 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.
// Check early if empty translations 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->_unsetEmptyFields($entity);
}

$this->_bundleTranslatedFields($entity);
Expand Down Expand Up @@ -670,6 +640,41 @@ protected function _bundleTranslatedFields($entity)
$entity->set('_i18n', $contents);
}

/**
* Unset empty translations to avoid persistence.
* Should only be called if $this->_config['allowEmptyTranslations'] is false
*
* @param \Cake\Datasource\EntityInterface $entity The entity to check for empty translations fields inside.
* @return void
*/
protected function _unsetEmptyFields(EntityInterface $entity)
{
$translations = (array)$entity->get('_translations');
foreach ($translations as $locale => $translation) {
$fields = $translation->extract($this->_config['fields'], false);
foreach ($fields as $field => $value) {
if (strlen($value) === 0) {
$translation->unsetProperty($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]);
}
}

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

/**
* Returns the ids found for each of the condition arrays passed for the translations
* table. Each records is indexed by the corresponding position to the conditions array
Expand Down
11 changes: 11 additions & 0 deletions tests/TestCase/ORM/Behavior/TranslateBehaviorTest.php
Expand Up @@ -912,6 +912,17 @@ public function testMultipleAllowEmptyFalse()
])
->first();
$this->assertSame('Hallo', $deBody->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);
}

/**
Expand Down

0 comments on commit fbdb8bc

Please sign in to comment.