Browse Source

Backport ascii validation to 3.next

Mark Story 5 years ago
parent
commit
b18ec130d5

+ 44 - 2
src/Validation/Validation.php

@@ -155,9 +155,10 @@ class Validation
     }
 
     /**
-     * Checks that a string contains only integer or letters
+     * Checks that a string contains only integer or letters.
      *
-     * Returns true if string contains only integer or letters
+     * This method's definition of letters and integers includes unicode characters.
+     * Use `asciiAlphaNumeric()` if you want to exclude unicode.
      *
      * @param string $check Value to check
      * @return bool Success
@@ -172,6 +173,46 @@ class Validation
     }
 
     /**
+     * Checks that a doesn't contain any alpha numeric characters
+     *
+     * This method's definition of letters and integers includes unicode characters.
+     * Use `notAsciiAlphaNumeric()` if you want to exclude ascii only.
+     *
+     * @param mixed $check Value to check
+     * @return bool Success
+     */
+    public static function notAlphaNumeric($check): bool
+    {
+        return !static::alphaNumeric($check);
+    }
+
+    /**
+     * Checks that a string contains only ascii integer or letters.
+     *
+     * @param mixed $check Value to check
+     * @return bool Success
+     */
+    public static function asciiAlphaNumeric($check): bool
+    {
+        if ((empty($check) && $check !== '0') || !is_scalar($check)) {
+            return false;
+        }
+
+        return self::_check($check, '/^[[:alnum:]]+$/');
+    }
+
+    /**
+     * Checks that a doesn't contain any non-ascii alpha numeric characters
+     *
+     * @param mixed $check Value to check
+     * @return bool Success
+     */
+    public static function notAsciiAlphaNumeric($check): bool
+    {
+        return !static::asciiAlphaNumeric($check);
+    }
+
+    /**
      * Checks that a string length is within specified range.
      * Spaces are included in the character count.
      * Returns true if string matches value min, max, or between min and max,
@@ -470,6 +511,7 @@ class Validation
      * @param string $check Value to check
      * @param int $count Number of non-alphanumerics to check for
      * @return bool Success
+     * @deprecated 3.9.0 Use notAlphaNumeric() instead. Will be removed in 5.0
      */
     public static function containsNonAlphaNumeric($check, $count = 1)
     {

+ 58 - 0
src/Validation/Validator.php

@@ -1300,6 +1300,63 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
     }
 
     /**
+     * Add a non-alphanumeric rule to a field.
+     *
+     * @param string $field The field you want to apply the rule to.
+     * @param string|null $message The error message when the rule fails.
+     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
+     *   true when the validation rule should be applied.
+     * @see \Cake\Validation\Validation::notAlphaNumeric()
+     * @return $this
+     */
+    public function notAlphaNumeric($field, $message = null, $when = null)
+    {
+        $extra = array_filter(['on' => $when, 'message' => $message]);
+
+        return $this->add($field, 'notAlphaNumeric', $extra + [
+            'rule' => 'notAlphaNumeric',
+        ]);
+    }
+
+    /**
+     * Add an ascii-alphanumeric rule to a field.
+     *
+     * @param string $field The field you want to apply the rule to.
+     * @param string|null $message The error message when the rule fails.
+     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
+     *   true when the validation rule should be applied.
+     * @see \Cake\Validation\Validation::asciiAlphaNumeric()
+     * @return $this
+     */
+    public function asciiAlphaNumeric($field, $message = null, $when = null)
+    {
+        $extra = array_filter(['on' => $when, 'message' => $message]);
+
+        return $this->add($field, 'asciiAlphaNumeric', $extra + [
+            'rule' => 'asciiAlphaNumeric',
+        ]);
+    }
+
+    /**
+     * Add a non-ascii alphanumeric rule to a field.
+     *
+     * @param string $field The field you want to apply the rule to.
+     * @param string|null $message The error message when the rule fails.
+     * @param string|callable|null $when Either 'create' or 'update' or a callable that returns
+     *   true when the validation rule should be applied.
+     * @see \Cake\Validation\Validation::notAlphaNumeric()
+     * @return $this
+     */
+    public function notAsciiAlphaNumeric($field, $message = null, $when = null)
+    {
+        $extra = array_filter(['on' => $when, 'message' => $message]);
+
+        return $this->add($field, 'notAsciiAlphaNumeric', $extra + [
+            'rule' => 'notAsciiAlphaNumeric',
+        ]);
+    }
+
+    /**
      * Add an rule that ensures a string length is within a range.
      *
      * @param string $field The field you want to apply the rule to.
@@ -1642,6 +1699,7 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable
      *   true when the validation rule should be applied.
      * @see \Cake\Validation\Validation::containsNonAlphaNumeric()
      * @return $this
+     * @deprecated 3.9.0 Use notAlphaNumeric() instead. Will be removed in 5.0
      */
     public function containsNonAlphaNumeric($field, $limit = 1, $message = null, $when = null)
     {

+ 140 - 48
tests/TestCase/Validation/ValidationTest.php

@@ -145,6 +145,96 @@ class ValidationTest extends TestCase
     }
 
     /**
+     * testNotAlphaNumeric method
+     *
+     * @return void
+     */
+    public function testNotAlphaNumeric()
+    {
+        $this->assertFalse(Validation::notAlphaNumeric('frferrf'));
+        $this->assertFalse(Validation::notAlphaNumeric('12234'));
+        $this->assertFalse(Validation::notAlphaNumeric('1w2e2r3t4y'));
+        $this->assertFalse(Validation::notAlphaNumeric('0'));
+        $this->assertFalse(Validation::notAlphaNumeric('abçďĕʑʘπй'));
+        $this->assertFalse(Validation::notAlphaNumeric('ˇˆๆゞ'));
+        $this->assertFalse(Validation::notAlphaNumeric('אกあアꀀ豈'));
+        $this->assertFalse(Validation::notAlphaNumeric('Džᾈᾨ'));
+        $this->assertFalse(Validation::notAlphaNumeric('ÆΔΩЖÇ'));
+
+        $this->assertTrue(Validation::notAlphaNumeric('12 234'));
+        $this->assertTrue(Validation::notAlphaNumeric('dfd 234'));
+        $this->assertTrue(Validation::notAlphaNumeric("0\n"));
+        $this->assertTrue(Validation::notAlphaNumeric("\n"));
+        $this->assertTrue(Validation::notAlphaNumeric("\t"));
+        $this->assertTrue(Validation::notAlphaNumeric("\r"));
+        $this->assertTrue(Validation::notAlphaNumeric(' '));
+        $this->assertTrue(Validation::notAlphaNumeric(''));
+    }
+
+    /**
+     * testAsciiAlphaNumeric method
+     *
+     * @return void
+     */
+    public function testAsciiAlphaNumeric()
+    {
+        $this->assertTrue(Validation::asciiAlphaNumeric('frferrf'));
+        $this->assertTrue(Validation::asciiAlphaNumeric('12234'));
+        $this->assertTrue(Validation::asciiAlphaNumeric('1w2e2r3t4y'));
+        $this->assertTrue(Validation::asciiAlphaNumeric('0'));
+
+        $this->assertFalse(Validation::asciiAlphaNumeric('1 two'));
+        $this->assertFalse(Validation::asciiAlphaNumeric('abçďĕʑʘπй'));
+        $this->assertFalse(Validation::asciiAlphaNumeric('ˇˆๆゞ'));
+        $this->assertFalse(Validation::asciiAlphaNumeric('אกあアꀀ豈'));
+        $this->assertFalse(Validation::asciiAlphaNumeric('Džᾈᾨ'));
+        $this->assertFalse(Validation::asciiAlphaNumeric('ÆΔΩЖÇ'));
+        $this->assertFalse(Validation::asciiAlphaNumeric('12 234'));
+        $this->assertFalse(Validation::asciiAlphaNumeric('dfd 234'));
+        $this->assertFalse(Validation::asciiAlphaNumeric("\n"));
+        $this->assertFalse(Validation::asciiAlphaNumeric("\t"));
+        $this->assertFalse(Validation::asciiAlphaNumeric("\r"));
+        $this->assertFalse(Validation::asciiAlphaNumeric(' '));
+        $this->assertFalse(Validation::asciiAlphaNumeric(''));
+    }
+
+    /**
+     * testAlphaNumericPassedAsArray method
+     *
+     * @return void
+     */
+    public function testAsciiAlphaNumericPassedAsArray()
+    {
+        $this->assertFalse(Validation::asciiAlphaNumeric(['foo']));
+    }
+
+    /**
+     * testNotAlphaNumeric method
+     *
+     * @return void
+     */
+    public function testNotAsciiAlphaNumeric()
+    {
+        $this->assertFalse(Validation::notAsciiAlphaNumeric('frferrf'));
+        $this->assertFalse(Validation::notAsciiAlphaNumeric('12234'));
+        $this->assertFalse(Validation::notAsciiAlphaNumeric('1w2e2r3t4y'));
+        $this->assertFalse(Validation::notAsciiAlphaNumeric('0'));
+
+        $this->assertTrue(Validation::notAsciiAlphaNumeric('abçďĕʑʘπй'));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric('ˇˆๆゞ'));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric('אกあアꀀ豈'));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric('Džᾈᾨ'));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric('ÆΔΩЖÇ'));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric('12 234'));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric('dfd 234'));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric("\n"));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric("\t"));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric("\r"));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric(' '));
+        $this->assertTrue(Validation::notAsciiAlphaNumeric(''));
+    }
+
+    /**
      * testLengthBetween method
      *
      * @return void
@@ -2919,54 +3009,56 @@ class ValidationTest extends TestCase
      */
     public function testContainNonAlphaNumeric()
     {
-        $this->assertFalse(Validation::containsNonAlphaNumeric('abcdefghijklmnopqrstuvwxyz'));
-        $this->assertFalse(Validation::containsNonAlphaNumeric('ABCDEFGHIJKLMNOPQRSTUVWXYZ'));
-        $this->assertFalse(Validation::containsNonAlphaNumeric('0123456789'));
-        $this->assertFalse(Validation::containsNonAlphaNumeric('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'));
-
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#'));
-        $this->assertTrue(Validation::containsNonAlphaNumeric("0\n"));
-        $this->assertTrue(Validation::containsNonAlphaNumeric("\n"));
-        $this->assertTrue(Validation::containsNonAlphaNumeric("\t"));
-        $this->assertTrue(Validation::containsNonAlphaNumeric("\r"));
-        $this->assertTrue(Validation::containsNonAlphaNumeric(' '));
-
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#abcdef'));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abc#def'));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef#'));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abc def'));
-        $this->assertTrue(Validation::containsNonAlphaNumeric("abcdef\n"));
-
-        $this->assertTrue(Validation::containsNonAlphaNumeric('##abcdef', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef##', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#abcdef#', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#abc#def', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abc#def#', 2));
-
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#♥abcdef', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef#♥', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#abcdef♥', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#abc♥def', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abc#def♥', 2));
-
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#♥abcdef', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef#♥', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#abcdef♥', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#abc♥def', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abc#def♥', 2));
-
-        $this->assertTrue(Validation::containsNonAlphaNumeric('###abcdef', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abc###def', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef###', 2));
-        $this->assertTrue(Validation::containsNonAlphaNumeric('#abc#def#', 2));
-
-        $this->assertFalse(Validation::containsNonAlphaNumeric('##abcdef', 3));
-        $this->assertFalse(Validation::containsNonAlphaNumeric('abcdef##', 3));
-        $this->assertFalse(Validation::containsNonAlphaNumeric('abc##def', 3));
-        $this->assertFalse(Validation::containsNonAlphaNumeric('ab#cd#ef', 3));
-
-        // Non alpha numeric should not pass as array
-        $this->assertFalse(Validation::containsNonAlphaNumeric(['abc#']));
+        $this->deprecated(function () {
+            $this->assertFalse(Validation::containsNonAlphaNumeric('abcdefghijklmnopqrstuvwxyz'));
+            $this->assertFalse(Validation::containsNonAlphaNumeric('ABCDEFGHIJKLMNOPQRSTUVWXYZ'));
+            $this->assertFalse(Validation::containsNonAlphaNumeric('0123456789'));
+            $this->assertFalse(Validation::containsNonAlphaNumeric('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'));
+
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#'));
+            $this->assertTrue(Validation::containsNonAlphaNumeric("0\n"));
+            $this->assertTrue(Validation::containsNonAlphaNumeric("\n"));
+            $this->assertTrue(Validation::containsNonAlphaNumeric("\t"));
+            $this->assertTrue(Validation::containsNonAlphaNumeric("\r"));
+            $this->assertTrue(Validation::containsNonAlphaNumeric(' '));
+
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#abcdef'));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abc#def'));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef#'));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abc def'));
+            $this->assertTrue(Validation::containsNonAlphaNumeric("abcdef\n"));
+
+            $this->assertTrue(Validation::containsNonAlphaNumeric('##abcdef', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef##', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#abcdef#', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#abc#def', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abc#def#', 2));
+
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#♥abcdef', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef#♥', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#abcdef♥', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#abc♥def', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abc#def♥', 2));
+
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#♥abcdef', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef#♥', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#abcdef♥', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#abc♥def', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abc#def♥', 2));
+
+            $this->assertTrue(Validation::containsNonAlphaNumeric('###abcdef', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abc###def', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('abcdef###', 2));
+            $this->assertTrue(Validation::containsNonAlphaNumeric('#abc#def#', 2));
+
+            $this->assertFalse(Validation::containsNonAlphaNumeric('##abcdef', 3));
+            $this->assertFalse(Validation::containsNonAlphaNumeric('abcdef##', 3));
+            $this->assertFalse(Validation::containsNonAlphaNumeric('abc##def', 3));
+            $this->assertFalse(Validation::containsNonAlphaNumeric('ab#cd#ef', 3));
+
+            // Non alpha numeric should not pass as array
+            $this->assertFalse(Validation::containsNonAlphaNumeric(['abc#']));
+        });
     }
 
     /**

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

@@ -2392,6 +2392,42 @@ class ValidatorTest extends TestCase
     }
 
     /**
+     * Tests the notalphanumeric proxy method
+     *
+     * @return void
+     */
+    public function testNotAlphanumeric()
+    {
+        $validator = new Validator();
+        $this->assertProxyMethod($validator, 'notAlphaNumeric');
+        $this->assertEmpty($validator->validate(['username' => '$']));
+    }
+
+    /**
+     * Tests the asciialphanumeric proxy method
+     *
+     * @return void
+     */
+    public function testAsciiAlphanumeric()
+    {
+        $validator = new Validator();
+        $this->assertProxyMethod($validator, 'asciiAlphaNumeric');
+        $this->assertNotEmpty($validator->validate(['username' => '$']));
+    }
+
+    /**
+     * Tests the notalphanumeric proxy method
+     *
+     * @return void
+     */
+    public function testNotAsciiAlphanumeric()
+    {
+        $validator = new Validator();
+        $this->assertProxyMethod($validator, 'notAsciiAlphaNumeric');
+        $this->assertEmpty($validator->validate(['username' => '$']));
+    }
+
+    /**
      * Tests the lengthBetween proxy method
      *
      * @return void