Skip to content

Commit

Permalink
Adding support for nullable values.
Browse files Browse the repository at this point in the history
  • Loading branch information
maximkott committed Aug 26, 2016
1 parent 7ea8c8a commit d5524ce
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 1 deletion.
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
- [MinMaxLength](https://github.com/weew/validator/blob/master/src/Weew/Validator/Constraints/MinMaxLengthConstraint.php)
- [NotEmpty](https://github.com/weew/validator/blob/master/src/Weew/Validator/Constraints/NotEmptyConstraint.php)
- [NotNull](https://github.com/weew/validator/blob/master/src/Weew/Validator/Constraints/NotNullConstraint.php)
- [Nullable](https://github.com/weew/validator/blob/master/src/Weew/Validator/Constraints/NullableConstraint.php)
- [Null](https://github.com/weew/validator/blob/master/src/Weew/Validator/Constraints/NullConstraint.php)
- [Numeric](https://github.com/weew/validator/blob/master/src/Weew/Validator/Constraints/NumericConstraint.php)
- [Regex](https://github.com/weew/validator/blob/master/src/Weew/Validator/Constraints/RegexConstraint.php)
Expand Down
56 changes: 56 additions & 0 deletions src/Weew/Validator/Constraints/NullableConstraint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Weew\Validator\Constraints;

use Weew\Validator\IConstraint;
use Weew\Validator\IValidationData;

/**
* This constraint is used to allow to tag a specific
* subject as "optional". Validator will remove any errors
* that occurred for the given subject if the subject value
* is null or '' where this constraint has been applied.
*/
class NullableConstraint implements IConstraint {
/**
* @var string
*/
protected $message;

/**
* FloatConstraint constructor.
*
* @param string $message
*/
public function __construct($message = null) {
$this->message = $message;
}

/**
* @param $value
* @param IValidationData $data
*
* @return bool
*/
public function check($value, IValidationData $data = null) {
return array_contains([null, ''], $value) ? false : true;
}

/**
* @return string
*/
public function getMessage() {
if ($this->message !== null) {
return $this->message;
}

return 'May be null.';
}

/**
* @return array
*/
public function getOptions() {
return [];
}
}
62 changes: 62 additions & 0 deletions src/Weew/Validator/ValidationResultFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

namespace Weew\Validator;

use Weew\Validator\Constraints\NullableConstraint;

class ValidationResultFilter {
/**
* @param IValidationResult $result
*
* @return IValidationResult
*/
public function removeNullableErrors(IValidationResult $result) {
$nullableSubjects = $this->getNullableSubjects($result);
$filteredResult = new ValidationResult();

foreach ($result->getErrors() as $error) {
if ( ! $this->shouldErrorBeIgnored($nullableSubjects, $error)) {
$filteredResult->addError($error);
}
}

return $filteredResult;
}

/**
* @param IValidationResult $result
*
* @return array
*/
protected function getNullableSubjects(IValidationResult $result) {
$nullableSubjects = [];

foreach ($result->getErrors() as $error) {
if ($error->getConstraint() instanceof NullableConstraint) {
$nullableSubjects[] = $error->getSubject();
}
}

return $nullableSubjects;
}

/**
* @param array $nullableSubjects
* @param IValidationError $error
*
* @return bool
*/
protected function shouldErrorBeIgnored(array $nullableSubjects, IValidationError $error) {
if ($error->getConstraint() instanceof NullableConstraint) {
return true;
}

foreach ($nullableSubjects as $subject) {
if (str_starts_with($error->getSubject(), $subject)) {
return true;
}
}

return false;
}
}
13 changes: 12 additions & 1 deletion src/Weew/Validator/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,18 @@ protected function applyConstraints($data, array $groups) {
}
}

return $result;
return $this->filterResult($result);
}

/**
* @param IValidationResult $result
*
* @return ValidationResult
*/
protected function filterResult(IValidationResult $result) {
$resultFilter = new ValidationResultFilter();

return $resultFilter->removeNullableErrors($result);
}

/**
Expand Down
29 changes: 29 additions & 0 deletions tests/Weew/Validator/Constraints/NullableConstraintTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Tests\Weew\Validator\Constraints;

use PHPUnit_Framework_TestCase;
use Weew\Validator\Constraints\NullableConstraint;

class NullableConstraintTest extends PHPUnit_Framework_TestCase {
public function test_check() {
$c = new NullableConstraint();
$this->assertFalse($c->check(''));
$this->assertFalse($c->check(null));
$this->assertTrue($c->check('foo'));
$this->assertTrue($c->check(22));
}

public function test_get_options() {
$c = new NullableConstraint();
$this->assertEquals([], $c->getOptions());
}

public function test_get_message() {
$c = new NullableConstraint('foo');
$this->assertEquals('foo', $c->getMessage());

$c = new NullableConstraint();
$this->assertNotNull($c->getMessage());
}
}
31 changes: 31 additions & 0 deletions tests/Weew/Validator/ValidationResultFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Tests\Weew\Validator;

use PHPUnit_Framework_TestCase;
use Weew\Validator\Constraints\NotNullConstraint;
use Weew\Validator\Constraints\NullableConstraint;
use Weew\Validator\ValidationError;
use Weew\Validator\ValidationResult;
use Weew\Validator\ValidationResultFilter;

class ValidationResultFilterTest extends PHPUnit_Framework_TestCase {
public function test_removes_nullable_errors() {
$error1 = new ValidationError('foo.bar.baz', 'baz', new NotNullConstraint());
$error2 = new ValidationError('foo.bar.yolo', 'baz', new NotNullConstraint());
$error3 = new ValidationError('some.value', 'baz', new NotNullConstraint());
$error4 = new ValidationError('another.value', 'baz', new NotNullConstraint());
$error5 = new ValidationError('foo.bar', 'baz', new NullableConstraint());
$error6 = new ValidationError('foo', 'baz', new NotNullConstraint());
$errors = [$error1, $error2, $error3, $error4, $error5, $error6];

$result = new ValidationResult($errors);
$filter = new ValidationResultFilter();
$filteredResult = $filter->removeNullableErrors($result);

$this->assertEquals(3, $filteredResult->getErrorCount());
$this->assertTrue($filteredResult->getErrors()[0] === $error3);
$this->assertTrue($filteredResult->getErrors()[1] === $error4);
$this->assertTrue($filteredResult->getErrors()[2] === $error6);
}
}

0 comments on commit d5524ce

Please sign in to comment.