Skip to content

Commit 4a2d502

Browse files
committed
feat: add support for special validators
1 parent cf282cf commit 4a2d502

File tree

2 files changed

+88
-8
lines changed

2 files changed

+88
-8
lines changed

src/Form.php

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ class Form
5353
'regex' => '/%s/',
5454
];
5555

56+
/**
57+
* Special validation rules
58+
*/
59+
protected static $specialRules = [
60+
'array'
61+
];
62+
5663
/**
5764
* Validation error messages
5865
*/
@@ -61,9 +68,9 @@ class Form
6168
'email' => '{Field} must be a valid email address',
6269
'alpha' => '{Field} must contain only alphabets and spaces',
6370
'text' => '{Field} must contain only alphabets and spaces',
64-
'textOnly' => '{Field} must contain only alphabets',
65-
'alphaNum' => '{Field} must contain only alphabets and numbers',
66-
'alphaDash' => '{Field} must contain only alphabets, numbers, dashes and underscores',
71+
'textonly' => '{Field} must contain only alphabets',
72+
'alphanum' => '{Field} must contain only alphabets and numbers',
73+
'alphadash' => '{Field} must contain only alphabets, numbers, dashes and underscores',
6774
'username' => '{Field} must contain only alphabets, numbers and underscores',
6875
'number' => '{Field} must contain only numbers',
6976
'float' => '{Field} must contain only numbers',
@@ -75,18 +82,19 @@ class Form
7582
'contains' => '{Field} must contain %s',
7683
'boolean' => '{Field} must be a boolean',
7784
'in' => '{Field} must be one of the following: %s',
78-
'notIn' => '{Field} must not be one of the following: %s',
85+
'notin' => '{Field} must not be one of the following: %s',
7986
'ip' => '{Field} must be a valid IP address',
8087
'ipv4' => '{Field} must be a valid IPv4 address',
8188
'ipv6' => '{Field} must be a valid IPv6 address',
8289
'url' => '{Field} must be a valid URL',
8390
'domain' => '{Field} must be a valid domain',
84-
'creditCard' => '{Field} must be a valid credit card number',
91+
'creditcard' => '{Field} must be a valid credit card number',
8592
'phone' => '{Field} must be a valid phone number',
8693
'uuid' => '{Field} must be a valid UUID',
8794
'slug' => '{Field} must be a valid slug',
8895
'json' => '{Field} must be a valid JSON string',
8996
'regex' => '{Field} must match the pattern %s',
97+
'array' => '{field} must be an array',
9098
];
9199

92100
/**
@@ -102,10 +110,38 @@ public static function test(string $rule, $value, $param = null, $field = null):
102110
{
103111
$rule = strtolower($rule);
104112

113+
if (strpos($rule, '(') !== false) {
114+
$ruleData = explode('(', $rule);
115+
$rule = $ruleData[0];
116+
117+
if (in_array($rule, static::$specialRules)) {
118+
$params = explode('|', str_replace(['(', ')'], '', $ruleData[1]));
119+
120+
if ($rule === 'array') {
121+
if (!is_array($value)) {
122+
return false;
123+
}
124+
125+
$isValid = true;
126+
127+
foreach ($params as $paramValue) {
128+
foreach ($value as $valueArrayItem) {
129+
if (!static::test($paramValue, $valueArrayItem)) {
130+
$isValid = false;
131+
}
132+
}
133+
}
134+
135+
return $isValid;
136+
}
137+
}
138+
}
139+
105140
if (!isset(static::$rules[$rule])) {
106141
throw new \Exception("Rule $rule does not exist");
107142
}
108143

144+
$param = is_string($param) ? trim($param, '()') : $param;
109145
$param = eval("return $param;");
110146

111147
if (is_callable(static::$rules[$rule])) {
@@ -136,7 +172,17 @@ public static function validate(array $data, array $rules)
136172

137173
foreach ($rules as $field => $userRules) {
138174
if (is_string($userRules)) {
139-
$userRules = explode('|', strtolower($userRules));
175+
if (strpos($userRules, '(') !== false) {
176+
$pattern = '/(array\([^)]+\))\|(\w+)/';
177+
178+
if (preg_match($pattern, $userRules, $matches)) {
179+
$userRules = [$matches[1], ...explode('|', strtolower($matches[2]))];
180+
} else {
181+
$userRules = explode('|', strtolower($userRules));
182+
}
183+
} else {
184+
$userRules = explode('|', strtolower($userRules));
185+
}
140186
}
141187

142188
foreach ($userRules as $rule) {
@@ -154,7 +200,7 @@ public static function validate(array $data, array $rules)
154200
$value = $data[$field] ?? null;
155201

156202
if (!static::test($rule[0], $value, $rule[1] ?? null, $field)) {
157-
$params = $rule[1] ?? null;
203+
$params = is_string($rule[1] ?? null) ? trim($rule[1], '()') : ($rule[1] ?? null);
158204
$params = eval("return $params;");
159205

160206
if (!is_array($params)) {
@@ -164,7 +210,7 @@ public static function validate(array $data, array $rules)
164210
$errorMessage = str_replace(
165211
['{field}', '{Field}', '{value}'],
166212
[$field, ucfirst($field), $value],
167-
static::$messages[$rule[0]] ?? '{Field} is invalid!'
213+
static::$messages[$rule[0]] ?? static::$messages[explode('(', $rule[0])[0] ?? 'any'] ?? '{Field} is invalid!'
168214
);
169215

170216
static::addError($field, sprintf($errorMessage, ...$params));

tests/array.test.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Leaf\Form;
6+
7+
test('special validation rules don\'t throw errors when used', function () {
8+
$itemsToValidate = ['specialItem' => ['wrong', 'wrong2', 'right@example.com']];
9+
10+
Form::validate($itemsToValidate, ['specialItem' => 'array(email)']);
11+
12+
expect(Form::errors())->toHaveKey('specialItem');
13+
});
14+
15+
test('array() can be used to validate arrays', function () {
16+
$itemsToValidate = ['specialItem2' => 'wrong', 'specialItem3' => ['item here']];
17+
18+
Form::validate($itemsToValidate, ['specialItem2' => 'array()']);
19+
20+
expect(Form::errors())->toHaveKey('specialItem2');
21+
expect(Form::errors())->not()->toHaveKey('specialItem3');
22+
});
23+
24+
test('array() can be used to validate array content', function () {
25+
$itemsToValidate = ['specialItem3' => ['wrong'], 'specialItem4' => ['mail@example.com']];
26+
27+
Form::validate($itemsToValidate, [
28+
'specialItem3' => 'array(email)',
29+
'specialItem4' => 'array(email)',
30+
]);
31+
32+
expect(Form::errors())->toHaveKey('specialItem3');
33+
expect(Form::errors())->not()->toHaveKey('specialItem4');
34+
});

0 commit comments

Comments
 (0)