Browse Source

Make allowMultipleNulls a constructor argument.

Previously this option was implemented as an additional context
parameter. That seemed a bit strange as the option could and probably
should be a constructor argument. Given that the option is only relevant
to the IsUnique rule there is no reason for the RulesChecker to be
handling it.
Mark Story 9 years ago
parent
commit
e02b8845b8

+ 10 - 3
src/ORM/Rule/IsUnique.php

@@ -30,13 +30,21 @@ class IsUnique
     protected $_fields;
 
     /**
+     * The options to use.
+     *
+     * @var array
+     */
+    protected $_options;
+
+    /**
      * Constructor.
      *
      * @param array $fields The list of fields to check uniqueness for
      */
-    public function __construct(array $fields)
+    public function __construct(array $fields, array $options = [])
     {
         $this->_fields = $fields;
+        $this->_options = $options + ['allowMultipleNulls' => true];
     }
 
     /**
@@ -52,8 +60,7 @@ class IsUnique
         if (!$entity->extract($this->_fields, true)) {
             return true;
         }
-        $options += ['allowMultipleNulls' => true];
-        $allowMultipleNulls = $options['allowMultipleNulls'];
+        $allowMultipleNulls = $this->_options['allowMultipleNulls'];
 
         $alias = $options['repository']->alias();
         $conditions = $this->_alias($alias, $entity->extract($this->_fields), $allowMultipleNulls);

+ 9 - 2
src/ORM/RulesChecker.php

@@ -40,11 +40,18 @@ class RulesChecker extends BaseRulesChecker
      * ```
      *
      * @param array $fields The list of fields to check for uniqueness.
-     * @param string|null $message The error message to show in case the rule does not pass.
+     * @param string|array|null $message The error message to show in case the rule does not pass. Can
+     *   also be an array of options. When an array, the 'message' key can be used to provide a message.
      * @return callable
      */
     public function isUnique(array $fields, $message = null)
     {
+        $options = [];
+        if (is_array($message)) {
+            $options = $message + ['message' => null];
+            $message = $options['message'];
+            unset($options['message']);
+        }
         if (!$message) {
             if ($this->_useI18n) {
                 $message = __d('cake', 'This value is already in use');
@@ -54,7 +61,7 @@ class RulesChecker extends BaseRulesChecker
         }
 
         $errorField = current($fields);
-        return $this->_addError(new IsUnique($fields), '_isUnique', compact('errorField', 'message'));
+        return $this->_addError(new IsUnique($fields, $options), '_isUnique', compact('errorField', 'message'));
     }
 
     /**

+ 9 - 3
tests/TestCase/ORM/RulesCheckerIntegrationTest.php

@@ -389,10 +389,13 @@ class RulesCheckerIntegrationTest extends TestCase
 
         $table = TableRegistry::get('SpecialTags');
         $rules = $table->rulesChecker();
-        $rules->add($rules->isUnique(['author_id']), ['allowMultipleNulls' => false]);
+        $rules->add($rules->isUnique(['author_id'], [
+            'allowMultipleNulls' => false,
+            'message' => 'All fields are required'
+        ]));
 
         $this->assertFalse($table->save($entity));
-        $this->assertEquals(['_isUnique' => 'This value is already in use'], $entity->errors('author_id'));
+        $this->assertEquals(['_isUnique' => 'All fields are required'], $entity->errors('author_id'));
 
         $entity->author_id = 11;
         $this->assertSame($entity, $table->save($entity));
@@ -418,7 +421,10 @@ class RulesCheckerIntegrationTest extends TestCase
 
         $table = TableRegistry::get('SpecialTags');
         $rules = $table->rulesChecker();
-        $rules->add($rules->isUnique(['author_id', 'article_id'], 'Nope'), ['allowMultipleNulls' => false]);
+        $rules->add($rules->isUnique(['author_id', 'article_id'], [
+            'allowMultipleNulls' => false,
+            'message' => 'Nope'
+        ]));
 
         $this->assertFalse($table->save($entity));
         $this->assertEquals(['author_id' => ['_isUnique' => 'Nope']], $entity->errors());