mirror of
https://github.com/Respect/Validation.git
synced 2024-06-04 14:52:17 +02:00
Create "Optional" rule
This commit is contained in:
parent
3e45647b81
commit
455ff9b318
28
docs/Optional.md
Normal file
28
docs/Optional.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Optional
|
||||
|
||||
- `v::optional(v $rule)`
|
||||
- `v::optional(v $rule, array $optionalValues)`
|
||||
|
||||
Validates if the given input is optional or not. By _optional_ you may interpret
|
||||
as `null` or an empty string (`''`).
|
||||
|
||||
```php
|
||||
v::optional(v::alpha())->validate(''); // true
|
||||
v::optional(v::digit())->validate(null); // true
|
||||
```
|
||||
|
||||
Also you can defined what values you want as optional values:
|
||||
|
||||
```php
|
||||
v::optional(v::alpha(), array(null))->validate(''); // false
|
||||
```
|
||||
|
||||
The example bellow returns false because only `null` is accepted as optional
|
||||
value, and `''` is not.
|
||||
|
||||
***
|
||||
See also:
|
||||
|
||||
* [NotEmpty](NotEmpty.md)
|
||||
* [NoWhitespace](NoWhitespace.md)
|
||||
* [NullValue](NullValue.md)
|
|
@ -53,6 +53,29 @@ Note that we used `v::string()` and `v::date()` in the beginning of the validato
|
|||
Although is not mandatory, it is a good practice to use the type of the
|
||||
validated object as the first node in the chain.
|
||||
|
||||
## Input optional
|
||||
|
||||
On oldest versions of Respect\Validation all validators treat input as optional
|
||||
and accept an empty string input as valid. Even though a useful feature that
|
||||
caused a lot of troubles for our team and neither was an obvious behavior. Also
|
||||
there was some people who likes to accept `null` as optional value, not only an
|
||||
empty string.
|
||||
|
||||
For that reason all rules are mandatory now but if you want to treat a value as
|
||||
optional you can use `v::optional()` rule:
|
||||
|
||||
```php
|
||||
v::alpha()->validate(''); // false input required
|
||||
v::alpha()->validate(null); // false input required
|
||||
|
||||
v::optional(v::alpha())->validate(''); // true
|
||||
v::optional(v::alpha())->validate(null); // true
|
||||
```
|
||||
|
||||
By _optional_ you may interpret as `null` or an empty string (`''`).
|
||||
|
||||
See more on [Optional](Optional.md).
|
||||
|
||||
## Negating Rules
|
||||
|
||||
You can use the `v::not()` to negate any rule:
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* [Callback](Callback.md)
|
||||
* [FilterVar](FilterVar.md)
|
||||
* [Not](Not.md)
|
||||
* [Optional](Optional.md)
|
||||
* [Type](Type.md)
|
||||
* [When](When.md)
|
||||
|
||||
|
@ -250,6 +251,7 @@
|
|||
* [Object](Object.md)
|
||||
* [Odd](Odd.md)
|
||||
* [OneOf](OneOf.md)
|
||||
* [Optional](Optional.md)
|
||||
* [PerfectSquare](PerfectSquare.md)
|
||||
* [Phone](Phone.md)
|
||||
* [Positive](Positive.md)
|
||||
|
|
33
library/Exceptions/OptionalException.php
Normal file
33
library/Exceptions/OptionalException.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Respect/Validation.
|
||||
*
|
||||
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
*
|
||||
* For the full copyright and license information, please view the "LICENSE.md"
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Respect\Validation\Exceptions;
|
||||
|
||||
class OptionalException extends ValidationException
|
||||
{
|
||||
const STANDARD = 0;
|
||||
const NAMED = 1;
|
||||
public static $defaultTemplates = array(
|
||||
self::MODE_DEFAULT => array(
|
||||
self::STANDARD => 'The value must be optional',
|
||||
self::NAMED => '{{name}} must be optional',
|
||||
),
|
||||
self::MODE_NEGATIVE => array(
|
||||
self::STANDARD => 'The value is required',
|
||||
self::NAMED => '{{name}} is required',
|
||||
),
|
||||
);
|
||||
|
||||
public function chooseTemplate()
|
||||
{
|
||||
return $this->getName() == '' ? static::STANDARD : static::NAMED;
|
||||
}
|
||||
}
|
58
library/Rules/Optional.php
Normal file
58
library/Rules/Optional.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Respect/Validation.
|
||||
*
|
||||
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
*
|
||||
* For the full copyright and license information, please view the "LICENSE.md"
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Respect\Validation\Rules;
|
||||
|
||||
use Respect\Validation\Validatable;
|
||||
use Respect\Validation\Exceptions\ComponentException;
|
||||
|
||||
class Optional extends AbstractWrapper
|
||||
{
|
||||
public $optionalValues;
|
||||
|
||||
public function __construct(Validatable $rule, array $optionalValues = array(null, ''))
|
||||
{
|
||||
$this->validatable = $rule;
|
||||
$this->optionalValues = $optionalValues;
|
||||
}
|
||||
|
||||
private function isOptional($input)
|
||||
{
|
||||
return in_array($input, $this->optionalValues, true);
|
||||
}
|
||||
|
||||
public function assert($input)
|
||||
{
|
||||
if ($this->isOptional($input)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::assert($input);
|
||||
}
|
||||
|
||||
public function check($input)
|
||||
{
|
||||
if ($this->isOptional($input)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::check($input);
|
||||
}
|
||||
|
||||
public function validate($input)
|
||||
{
|
||||
if ($this->isOptional($input)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::validate($input);
|
||||
}
|
||||
}
|
|
@ -92,6 +92,7 @@ use Respect\Validation\Rules\Key;
|
|||
* @method static Validator object()
|
||||
* @method static Validator odd()
|
||||
* @method static Validator oneOf()
|
||||
* @method static Validator optional(Validatable $rule, array $optionalValues = array(null, ''))
|
||||
* @method static Validator perfectSquare()
|
||||
* @method static Validator phone()
|
||||
* @method static Validator positive()
|
||||
|
|
14
tests/integration/optional-assert.phpt
Normal file
14
tests/integration/optional-assert.phpt
Normal file
|
@ -0,0 +1,14 @@
|
|||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
|
||||
v::optional(v::alpha())->assert('');
|
||||
v::optional(v::alpha())->assert(null);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
===DONE===
|
14
tests/integration/optional-check.phpt
Normal file
14
tests/integration/optional-check.phpt
Normal file
|
@ -0,0 +1,14 @@
|
|||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
|
||||
v::optional(v::alpha())->check('');
|
||||
v::optional(v::alpha())->check(null);
|
||||
?>
|
||||
===DONE===
|
||||
--EXPECTF--
|
||||
===DONE===
|
19
tests/integration/optional-validate.phpt
Normal file
19
tests/integration/optional-validate.phpt
Normal file
|
@ -0,0 +1,19 @@
|
|||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'vendor/autoload.php';
|
||||
|
||||
use Respect\Validation\Validator as v;
|
||||
|
||||
|
||||
var_dump(v::alpha()->validate(''));
|
||||
var_dump(v::alpha()->validate(null));
|
||||
|
||||
var_dump(v::optional(v::alpha())->validate(''));
|
||||
var_dump(v::optional(v::alpha())->validate(null));
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
130
tests/unit/Rules/OptionalTest.php
Normal file
130
tests/unit/Rules/OptionalTest.php
Normal file
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Respect/Validation.
|
||||
*
|
||||
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||
*
|
||||
* For the full copyright and license information, please view the "LICENSE.md"
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Respect\Validation\Rules;
|
||||
|
||||
/**
|
||||
* @group rule
|
||||
* @covers Respect\Validation\Rules\Optional
|
||||
* @covers Respect\Validation\Exceptions\OptionalException
|
||||
*/
|
||||
class OptionalTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testShouldAcceptInstanceOfValidatobleOnConstructor()
|
||||
{
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$rule = new Optional($validatable);
|
||||
|
||||
$this->assertSame($validatable, $rule->getValidatable());
|
||||
}
|
||||
|
||||
public function testShouldAcceptOptionalValuesOnConstructor()
|
||||
{
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$optionalValues = array(null, '', ' ', '0');
|
||||
$rule = new Optional($validatable, $optionalValues);
|
||||
|
||||
$this->assertSame($optionalValues, $rule->optionalValues);
|
||||
}
|
||||
|
||||
public function testShouldHaveDefaultOptionalValues()
|
||||
{
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$expectedOptionalValues = array(null, '');
|
||||
$rule = new Optional($validatable);
|
||||
|
||||
$this->assertSame($expectedOptionalValues, $rule->optionalValues);
|
||||
}
|
||||
|
||||
public function testShouldNotValidateRuleWhenInputIsOptional()
|
||||
{
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$validatable
|
||||
->expects($this->never())
|
||||
->method('validate');
|
||||
|
||||
$rule = new Optional($validatable);
|
||||
|
||||
$this->assertTrue($rule->validate(''));
|
||||
}
|
||||
|
||||
public function testShouldValidateRuleWhenInputIsNotOptional()
|
||||
{
|
||||
$input = 'foo';
|
||||
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$validatable
|
||||
->expects($this->once())
|
||||
->method('validate')
|
||||
->with($input)
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$rule = new Optional($validatable);
|
||||
|
||||
$this->assertTrue($rule->validate($input));
|
||||
}
|
||||
|
||||
public function testShouldNotAssertRuleWhenInputIsOptional()
|
||||
{
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$validatable
|
||||
->expects($this->never())
|
||||
->method('assert');
|
||||
|
||||
$rule = new Optional($validatable);
|
||||
|
||||
$this->assertTrue($rule->assert(''));
|
||||
}
|
||||
|
||||
public function testShouldAssertRuleWhenInputIsNotOptional()
|
||||
{
|
||||
$input = 'foo';
|
||||
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$validatable
|
||||
->expects($this->once())
|
||||
->method('assert')
|
||||
->with($input)
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$rule = new Optional($validatable);
|
||||
|
||||
$this->assertTrue($rule->assert($input));
|
||||
}
|
||||
|
||||
public function testShouldNotCheckRuleWhenInputIsOptional()
|
||||
{
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$validatable
|
||||
->expects($this->never())
|
||||
->method('check');
|
||||
|
||||
$rule = new Optional($validatable);
|
||||
|
||||
$this->assertTrue($rule->check(''));
|
||||
}
|
||||
|
||||
public function testShouldCheckRuleWhenInputIsNotOptional()
|
||||
{
|
||||
$input = 'foo';
|
||||
|
||||
$validatable = $this->getMock('Respect\\Validation\\Validatable');
|
||||
$validatable
|
||||
->expects($this->once())
|
||||
->method('check')
|
||||
->with($input)
|
||||
->will($this->returnValue(true));
|
||||
|
||||
$rule = new Optional($validatable);
|
||||
|
||||
$this->assertTrue($rule->check($input));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue