Skip to content

Commit 396112e

Browse files
committed
Add nullable validation rule
1 parent 6eb57d8 commit 396112e

File tree

4 files changed

+112
-15
lines changed

4 files changed

+112
-15
lines changed

src/Support/Str.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,17 @@ public static function fixUTF8(string $garbled_utf8_string): string
488488
return Encoding::fixUTF8($garbled_utf8_string);
489489
}
490490

491+
/**
492+
* Check if the string is empty
493+
*
494+
* @param string $str
495+
* @return bool
496+
*/
497+
public static function isEmpty(string $str): bool
498+
{
499+
return trim($str) === '' || $str === '' || $str === null || strlen($str) === 0;
500+
}
501+
491502
/**
492503
* __call
493504
*
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Bow\Validation\Rules;
6+
7+
use Bow\Support\Str;
8+
9+
trait NullableRule
10+
{
11+
/**
12+
* Compile Nullable Rule
13+
*
14+
* [nullable] Check that the content of the field is nullable
15+
*
16+
* @param string $key
17+
* @param string $masque
18+
* @return void
19+
*/
20+
protected function compileNullable(string $key, string $masque): void
21+
{
22+
if (!preg_match("/^nullable$/", $masque, $match)) {
23+
return;
24+
}
25+
26+
if (!isset($this->inputs[$key]) || $this->inputs[$key] === null || (is_string($this->inputs[$key]) && Str::isEmpty($this->inputs[$key]))) {
27+
return;
28+
}
29+
30+
$this->last_message = $this->lexical('nullable', $key);
31+
32+
$this->fails = true;
33+
34+
$this->errors[$key][] = [
35+
"masque" => $masque,
36+
"message" => $this->last_message
37+
];
38+
}
39+
}

src/Validation/Validator.php

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Bow\Validation\Rules\DatabaseRule;
99
use Bow\Validation\Rules\DatetimeRule;
1010
use Bow\Validation\Rules\EmailRule;
11+
use Bow\Validation\Rules\NullableRule;
1112
use Bow\Validation\Rules\NumericRule;
1213
use Bow\Validation\Rules\RegexRule;
1314
use Bow\Validation\Rules\StringRule;
@@ -21,6 +22,7 @@ class Validator
2122
use NumericRule;
2223
use StringRule;
2324
use RegexRule;
25+
use NullableRule;
2426

2527
/**
2628
* The Fails flag
@@ -63,6 +65,7 @@ class Validator
6365
* @var array
6466
*/
6567
protected array $rules = [
68+
'Nullable',
6669
'Required',
6770
"RequiredIf",
6871
'Max',
@@ -147,21 +150,8 @@ public function validate(array $inputs, array $rules): Validate
147150
* Formatting and validation of each rule
148151
* eg. name => "required|max:100|alpha"
149152
*/
150-
foreach ($rules as $key => $rule) {
151-
foreach (explode("|", $rule) as $masque) {
152-
// In the box there is a | super flux.
153-
if (is_int($masque) || Str::len($masque) == "") {
154-
continue;
155-
}
156-
157-
// Mask on the required rule
158-
foreach ($this->rules as $rule) {
159-
$this->{'compile' . $rule}($key, $masque);
160-
if ($rule == 'Required' && $this->fails) {
161-
break;
162-
}
163-
}
164-
}
153+
foreach ($rules as $field => $rule) {
154+
$this->checkRule($rule, $field);
165155
}
166156

167157
return new Validate(
@@ -170,4 +160,29 @@ public function validate(array $inputs, array $rules): Validate
170160
$this->errors
171161
);
172162
}
163+
164+
/**
165+
* Check atomic rule
166+
*
167+
* @param string $rule
168+
* @param string $field
169+
* @return void
170+
*/
171+
private function checkRule(string $rule, string $field): void
172+
{
173+
foreach (explode("|", $rule) as $masque) {
174+
// In the box there is a | super flux.
175+
if (is_int($masque) || Str::len($masque) == "") {
176+
continue;
177+
}
178+
179+
// Mask on the required rule
180+
foreach ($this->rules as $rule) {
181+
$this->{'compile' . $rule}($field, $masque);
182+
if ($rule == 'Required' && $this->fails) {
183+
break;
184+
}
185+
}
186+
}
187+
}
173188
}

tests/Validation/ValidationTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,4 +474,36 @@ public function test_regex_rule_fails_with_invalid_phone_format()
474474
);
475475
$this->assertTrue($validation->fails());
476476
}
477+
478+
// ==================== Nullable Rule ====================
479+
480+
public function test_nullable_rule_passes_with_null_value()
481+
{
482+
$validation = Validator::make(['name' => null], ['name' => 'nullable']);
483+
$this->assertFalse($validation->fails());
484+
}
485+
486+
public function test_nullable_rule_passes_with_missing_field()
487+
{
488+
$validation = Validator::make([], ['name' => 'nullable']);
489+
$this->assertFalse($validation->fails());
490+
}
491+
492+
public function test_nullable_rule_passes_with_value()
493+
{
494+
$validation = Validator::make(['name' => 'Bow'], ['name' => 'nullable']);
495+
$this->assertFalse($validation->fails());
496+
}
497+
498+
public function test_nullable_and_required_rule_fails_with_null()
499+
{
500+
$validation = Validator::make(['name' => null], ['name' => 'nullable|required']);
501+
$this->assertTrue($validation->fails());
502+
}
503+
504+
public function test_nullable_and_required_rule_passes_with_value()
505+
{
506+
$validation = Validator::make(['name' => 'Bow'], ['name' => 'nullable|required']);
507+
$this->assertFalse($validation->fails());
508+
}
477509
}

0 commit comments

Comments
 (0)