Browse Source

Merge pull request #8621 from JayPHP/checkNull_on_IsUnique

CheckNull option for IsUnique
José Lorenzo Rodríguez 10 years ago
parent
commit
88138afbc0

+ 14 - 0
src/ORM/Rule/IsUnique.php

@@ -53,6 +53,11 @@ class IsUnique
             return true;
         }
 
+        $allowMultipleNulls = true;
+        if (isset($options['allowMultipleNulls'])) {
+            $allowMultipleNulls = $options['allowMultipleNulls'] === true ? true : false;
+        }
+        
         $alias = $options['repository']->alias();
         $conditions = $this->_alias($alias, $entity->extract($this->_fields));
         if ($entity->isNew() === false) {
@@ -63,6 +68,15 @@ class IsUnique
             }
         }
 
+        if (!$allowMultipleNulls) {
+            foreach ($conditions as $key => $value) {
+                if ($value === null) {
+                    $conditions[$key . ' IS'] = $value;
+                    unset($conditions[$key]);
+                }
+            }
+        }
+
         return !$options['repository']->exists($conditions);
     }
 

+ 2 - 1
tests/Fixture/SpecialTagsFixture.php

@@ -48,6 +48,7 @@ class SpecialTagsFixture extends TestFixture
      */
     public $records = [
         ['article_id' => 1, 'tag_id' => 3, 'highlighted' => false, 'highlighted_time' => null, 'author_id' => 1],
-        ['article_id' => 2, 'tag_id' => 1, 'highlighted' => true, 'highlighted_time' => '2014-06-01 10:10:00', 'author_id' => 2]
+        ['article_id' => 2, 'tag_id' => 1, 'highlighted' => true, 'highlighted_time' => '2014-06-01 10:10:00', 'author_id' => 2],
+        ['article_id' => 10, 'tag_id' => 10, 'highlighted' => true, 'highlighted_time' => '2014-06-01 10:10:00', 'author_id' => null]
     ];
 }

+ 58 - 1
tests/TestCase/ORM/RulesCheckerIntegrationTest.php

@@ -29,7 +29,7 @@ class RulesCheckerIntegrationTest extends TestCase
      *
      * @var array
      */
-    public $fixtures = ['core.articles', 'core.articles_tags', 'core.authors', 'core.tags'];
+    public $fixtures = ['core.articles', 'core.articles_tags', 'core.authors', 'core.tags', 'core.special_tags'];
 
     /**
      * Tear down
@@ -370,6 +370,63 @@ class RulesCheckerIntegrationTest extends TestCase
     }
 
     /**
+     * Tests isUnique with allowMultipleNulls
+     *
+     * @group save
+     * @return void
+     */
+    public function testIsUniqueAllowMultipleNulls()
+    {
+        $entity = new Entity([
+            'article_id' => 11,
+            'tag_id' => 11,
+            'author_id' => null
+        ]);
+
+        $table = TableRegistry::get('SpecialTags');
+        $rules = $table->rulesChecker();
+        $rules->add($rules->isUnique(['author_id']), ['allowMultipleNulls' => false]);
+
+        $this->assertFalse($table->save($entity));
+        $this->assertEquals(['_isUnique' => 'This value is already in use'], $entity->errors('author_id'));
+
+        $entity->author_id = 11;
+        $this->assertSame($entity, $table->save($entity));
+
+        $entity = $table->get(1);
+        $entity->dirty('author_id', true);
+        $this->assertSame($entity, $table->save($entity));
+    }
+
+    /**
+     * Tests isUnique with multiple fields and allowMultipleNulls
+     *
+     * @group save
+     * @return void
+     */
+    public function testIsUniqueMultipleFieldsAllowMultipleNulls()
+    {
+        $entity = new Entity([
+            'article_id' => 10,
+            'tag_id' => 12,
+            'author_id' => null
+        ]);
+
+        $table = TableRegistry::get('SpecialTags');
+        $rules = $table->rulesChecker();
+        $rules->add($rules->isUnique(['author_id', 'article_id'], 'Nope'), ['allowMultipleNulls' => false]);
+
+        $this->assertFalse($table->save($entity));
+        $this->assertEquals(['author_id' => ['_isUnique' => 'Nope']], $entity->errors());
+
+        $entity->clean();
+        $entity->article_id = 10;
+        $entity->tag_id = 12;
+        $entity->author_id = 12;
+        $this->assertSame($entity, $table->save($entity));
+    }
+
+    /**
      * Tests the existsIn domain rule
      *
      * @group save