Skip to content
Permalink
Browse files

Don't mutate ExistsIn fields.

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 3990241bd30564ff1f515c024eea38c444d652dd
Showing with 42 additions and 3 deletions.
  1. +4 −3 src/ORM/Rule/ExistsIn.php
  2. +38 −0 tests/TestCase/ORM/RulesCheckerIntegrationTest.php
@@ -92,6 +92,7 @@ public function __invoke(EntityInterface $entity, array $options)
$this->_repository = $repository;
}
$fields = $this->_fields;
$source = $target = $this->_repository;
$isAssociation = $target instanceof Association;
$bindingKey = $isAssociation ? (array)$target->getBindingKey() : (array)$target->getPrimaryKey();
@@ -118,9 +119,9 @@ public function __invoke(EntityInterface $entity, array $options)
if ($this->_options['allowNullableNulls']) {
$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) {
unset($bindingKey[$i], $this->_fields[$i]);
unset($bindingKey[$i], $fields[$i]);
}
}
}
@@ -131,7 +132,7 @@ public function __invoke(EntityInterface $entity, array $options)
);
$conditions = array_combine(
$primary,
$entity->extract($this->_fields)
$entity->extract($fields)
);
return $target->exists($conditions);
@@ -1119,6 +1119,44 @@ public function testExistsInAllowNullableNullsOnInvalidKeySecond()
$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
*

0 comments on commit 3990241

Please sign in to comment.
You can’t perform that action at this time.