diff --git a/README.md b/README.md index 3c442d9..d5dd41f 100644 --- a/README.md +++ b/README.md @@ -48,11 +48,12 @@ $validator->defineType('User', [ 'name' => 'string', 'gender' => 'string', 'age' => '?integer', + 'rating' => '?integer|boolean', ]); ``` -This example defines a custom type named `User`, which have three properties. name and gender require be a -string, age requires be an integer but allows to be nullable. +This example defines a custom type named `User`, which have four properties. name and gender require be a +string, age requires be an integer but allows to be nullable, and rating required to integer or boolean and allows to be null. #### 2. Define a list type @@ -88,7 +89,7 @@ We can validate a type by the following two steps: #### 1. Create a Validator instance ```php -use rethinkphp\jsv\Validator; +use rethink\jsv\Validator; $validator = new Validator(); // $validator->defineType(...) Add your custom type if necessary diff --git a/src/Validator.php b/src/Validator.php index 2d13936..9c466f1 100644 --- a/src/Validator.php +++ b/src/Validator.php @@ -27,6 +27,7 @@ protected function builtInTypes() 'double' => 'is_double', 'boolean' => 'is_bool', 'string' => 'is_string', + 'null' => 'is_null', 'number' => [$this, 'isNumber'], 'array' => [$this, 'isArray'], 'object' => [$this, 'isObject'], @@ -243,9 +244,31 @@ protected function matchInternal($data, $type) if ($data === null) { return true; } + $type = substr($type, 1); } + if (is_string($type) && strpos($type, '|') !== false) { + $option = explode('|', $type); + + if (in_array($this->getType($data), $option)) { + $type = $this->getType($data); + } else { + foreach ($option as $key) { + $givenType = $this->getType($data); + $path = $this->getNormalizedPath(); + + $this->addError($path, "The path of '$path' requires to be a $type, $givenType is given"); + return false; + } + } + } + + return $this->matchInternalProcess($data, $type); + } + + protected function matchInternalProcess($data, $type) + { if (!is_string($type)) { $definition = $type; } else if (isset($this->types[$type])) { @@ -262,4 +285,4 @@ protected function matchInternal($data, $type) return $this->matchArray($data, $definition); } } -} +} \ No newline at end of file diff --git a/tests/JsonTypeTest.php b/tests/JsonTypeTest.php index 7d23938..0c460a3 100644 --- a/tests/JsonTypeTest.php +++ b/tests/JsonTypeTest.php @@ -62,6 +62,7 @@ protected function userType() 'gender' => 'string', 'age' => 'integer', 'tags' => ['string'], + 'rating' => ['?integer|double'], ]; } @@ -72,6 +73,7 @@ protected function userData() 'gender' => 'Male', 'age' => 18, 'tags' => ['Foo', 'Bar'], + 'rating' => [null, 1, 2.5], ]; } @@ -84,7 +86,6 @@ public function testMatchCustomType() $this->assertTrue($json->matches($this->userData(), 'user')); } - public function testMatchArrayOfCustomType() { $json = $this->createValidator(); @@ -174,6 +175,16 @@ public function typeErrorMessages() '$.foo[0]', "The path of '$.foo[0]' requires to be a string, integer is given", ], + [ + [ + 'foo' => [3, 2, 1], + ], + [ + 'foo' => ['string|double'], + ], + '$.foo[0]', + "The path of '$.foo[0]' requires to be a string|double, integer is given", + ], // Custom Types [