Skip to content

Commit

Permalink
Don't mutate ExistsIn fields.
Browse files Browse the repository at this point in the history
We should not mutate fields when applying an ExistsIn rule as it causes
problems with saveMany().

Thanks to @Nic0tiN for the test case

Refs #11880
  • Loading branch information
markstory committed Apr 2, 2018
1 parent 8ec460c commit 3990241
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/ORM/Rule/ExistsIn.php
Expand Up @@ -92,6 +92,7 @@ public function __invoke(EntityInterface $entity, array $options)
$this->_repository = $repository; $this->_repository = $repository;
} }


$fields = $this->_fields;
$source = $target = $this->_repository; $source = $target = $this->_repository;
$isAssociation = $target instanceof Association; $isAssociation = $target instanceof Association;
$bindingKey = $isAssociation ? (array)$target->getBindingKey() : (array)$target->getPrimaryKey(); $bindingKey = $isAssociation ? (array)$target->getBindingKey() : (array)$target->getPrimaryKey();
Expand All @@ -118,9 +119,9 @@ public function __invoke(EntityInterface $entity, array $options)


if ($this->_options['allowNullableNulls']) { if ($this->_options['allowNullableNulls']) {
$schema = $source->getSchema(); $schema = $source->getSchema();
foreach ($this->_fields as $i => $field) { foreach ($fields as $i => $field) {
if ($schema->getColumn($field) && $schema->isNullable($field) && $entity->get($field) === null) { if ($schema->getColumn($field) && $schema->isNullable($field) && $entity->get($field) === null) {
unset($bindingKey[$i], $this->_fields[$i]); unset($bindingKey[$i], $fields[$i]);
} }
} }
} }
Expand All @@ -131,7 +132,7 @@ public function __invoke(EntityInterface $entity, array $options)
); );
$conditions = array_combine( $conditions = array_combine(
$primary, $primary,
$entity->extract($this->_fields) $entity->extract($fields)
); );


return $target->exists($conditions); return $target->exists($conditions);
Expand Down
38 changes: 38 additions & 0 deletions tests/TestCase/ORM/RulesCheckerIntegrationTest.php
Expand Up @@ -1119,6 +1119,44 @@ public function testExistsInAllowNullableNullsOnInvalidKeySecond()
$this->assertEquals(['author_id' => ['_existsIn' => 'will error']], $entity->errors()); $this->assertEquals(['author_id' => ['_existsIn' => 'will error']], $entity->errors());
} }


/**
* Tests new allowNullableNulls with saveMany
*
* @return
*/
public function testExistsInAllowNullableNullsSaveMany()
{
$entities = [
new Entity([
'id' => 1,
'author_id' => null,
'site_id' => 1,
'name' => 'New Site Article without Author',
]),
new Entity([
'id' => 2,
'author_id' => 1,
'site_id' => 1,
'name' => 'New Site Article with Author',
]),
];
$table = TableRegistry::get('SiteArticles');
$table->belongsTo('SiteAuthors');
$rules = $table->rulesChecker();

$rules->add($rules->existsIn(['author_id', 'site_id'], 'SiteAuthors', [
'allowNullableNulls' => true,
'message' => 'will error with array_combine warning']));
$result = $table->saveMany($entities);
$this->assertCount(2, $result);

$this->assertInstanceOf(Entity::class, $result[0]);
$this->assertEmpty($result[0]->getErrors());

$this->assertInstanceOf(Entity::class, $result[1]);
$this->assertEmpty($result[1]->getErrors());
}

/** /**
* Tests using rules to prevent delete operations * Tests using rules to prevent delete operations
* *
Expand Down

0 comments on commit 3990241

Please sign in to comment.