Browse Source

Add notEmptyString() to Validator

Add a complement to allowEmptyString() that is easier to use than
allowEmptyString(..., false);
Mark Story 7 years ago
parent
commit
bf3c248a6a
2 changed files with 93 additions and 9 deletions
  1. 44 9
      src/Validation/Validator.php
  2. 49 0
      tests/TestCase/Validation/ValidatorTest.php

+ 44 - 9
src/Validation/Validator.php

@@ -807,6 +807,26 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
     }
 
     /**
+     * Requires a field to be not be an empty string.
+     *
+     * Creates rules that are complements to allowEmptyString()
+     *
+     * @param string $field The name of the field.
+     * @param string|null $message The message to show if the field is not
+     * @param bool|string|callable $when Indicates when the field is not allowed
+     *   to be empty. Valid values are false (always), 'create', 'update'. If a
+     *   callable is passed then the field will allowed to be empty only when
+     *   the callback returns false.
+     * @return $this
+     * @since 3.8.0
+     */
+    public function notEmptyString($field, $message = null, $when = false)
+    {
+        $when = $this->invertWhenClause($when);
+        return $this->allowEmptyFor($field, self::EMPTY_STRING, $when, $message);
+    }
+
+    /**
      * Allows a field to be an empty array.
      *
      * This method is equivalent to calling allowEmptyFor() with EMPTY_STRING +
@@ -1012,15 +1032,8 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
         foreach ($field as $fieldName => $setting) {
             $settings = $this->_convertValidatorToArray($fieldName, $defaults, $setting);
             $fieldName = current(array_keys($settings));
-            $whenSetting = $settings[$fieldName]['when'];
-
-            if ($whenSetting === 'create' || $whenSetting === 'update') {
-                $whenSetting = $whenSetting === 'create' ? 'update' : 'create';
-            } elseif (is_callable($whenSetting)) {
-                $whenSetting = function ($context) use ($whenSetting) {
-                    return !$whenSetting($context);
-                };
-            }
+
+            $whenSetting = $this->invertWhenClause($settings[$fieldName]['when']);
 
             $this->field($fieldName)->allowEmpty($whenSetting);
             if ($settings[$fieldName]['message']) {
@@ -1032,6 +1045,28 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
     }
 
     /**
+     * Invert a when clause for creating notEmpty rules
+     *
+     * @param bool|string|callable $when Indicates when the field is not allowed
+     *   to be empty. Valid values are true (always), 'create', 'update'. If a
+     *   callable is passed then the field will allowed to be empty only when
+     *   the callback returns false.
+     * @return bool|string|callable
+     */
+    protected function invertWhenClause($when)
+    {
+        if ($when === 'create' || $when === 'update') {
+            return $when === 'create' ? 'update' : 'create';
+        } elseif (is_callable($when)) {
+            return function ($context) use ($when) {
+                return !$when($context);
+            };
+        }
+
+        return $when;
+    }
+
+    /**
      * Add a notBlank rule to a field.
      *
      * @param string $field The field you want to apply the rule to.

+ 49 - 0
tests/TestCase/Validation/ValidatorTest.php

@@ -798,6 +798,55 @@ class ValidatorTest extends TestCase
     }
 
     /**
+     * Tests the notEmptyString method
+     *
+     * @return void
+     */
+    public function testNotEmptyString()
+    {
+        $validator = new Validator();
+        $validator->notEmptyString('title');
+
+        $this->assertFalse($validator->isEmptyAllowed('title', true));
+        $this->assertFalse($validator->isEmptyAllowed('title', false));
+
+        $data = ['title' => '0'];
+        $this->assertEmpty($validator->errors($data));
+
+        $data = ['title' => 0];
+        $this->assertEmpty($validator->errors($data), 'empty ok on create');
+        $this->assertEmpty($validator->errors($data, false), 'empty ok on update');
+
+        $data = ['title' => []];
+        $this->assertEmpty($validator->errors($data), 'empty array is no good');
+    }
+
+    /**
+     * Test notEmptyString with explicit create.
+     *
+     * @return void
+     */
+    public function testNotEmptyStringCreate()
+    {
+        $validator = new Validator();
+        $validator->notEmptyString('title', 'message', 'create');
+        $this->assertFalse($validator->isEmptyAllowed('title', true));
+        $this->assertTrue($validator->isEmptyAllowed('title', false));
+
+        $expected = [
+            'title' => ['_empty' => 'message'],
+        ];
+        $data = ['title' => null];
+        $this->assertSame($expected, $validator->errors($data, true));
+
+        $data = ['title' => ''];
+        $this->assertSame($expected, $validator->errors($data, true));
+
+        $data = ['title' => ''];
+        $this->assertEmpty($validator->errors($data, false), 'empty allowed on update');
+    }
+
+    /**
      * Tests the allowEmptyArray method
      *
      * @return void