Skip to content

Commit 7d461da

Browse files
add new validation rules
1 parent c012ec5 commit 7d461da

14 files changed

+634
-51
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to `shergela/validation-rule` will be documented in this file.
44

5+
## 1.0.1 - Friday 08, August - 2024
6+
7+
- add new `separateIntegersByComma()` method
8+
- add new `separateStringsByComma()` method
9+
- add new `separateStringsByUnderscore()` method
10+
511
## 1.0.0 - Tuesday 23, July - 2024
612

713
- add new `size()` method

README.md

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -28,48 +28,48 @@ return [
2828

2929
## Available rules (47)
3030

31-
| **Methods** | **Laravel Rule** | **Methods** | **Rule** |
32-
|:-------------------------:|:-----------------------:|:---------------------:|:--------------------------:|
33-
| Rule::required() | required | ->startsWith() | starts_with:foo,bar... |
34-
| Rule::nullable() | nullable | ->uppercaseFirst() | new UppercaseFirstLetter() |
35-
| Rule::boolean() | boolean | ->size() | size |
36-
| Rule::rules() | custom rules | ->endsWith() | ends_with:foo,bar |
37-
| ->email() | email | ->doesntStartWith() | doesnt_start_with:foo,bar |
38-
| ->uniqueEmail() | unique:users,email | ->doesntEndWith() | doesnt_end_with:foo,bar |
39-
| ->min() | min | ->in() | in:foo,bar... |
40-
| ->max() | max | ->notIn() | not_in:foo,bar,baz... |
41-
| ->minDigits() | min_digits | | |
42-
| ->maxDigits() | max_digits | | |
43-
| ->integer() | integer | | |
44-
| ->numeric() | numeric | | |
45-
| ->digits() | digits:1 | | |
46-
| ->digitsBetween() | digits:1,4 | | |
47-
| ->decimal() | decimal | | |
48-
| ->alpha() | alpha | | |
49-
| ->alphaDash() | alpha_dash | | |
50-
| ->alphaNum() | alpha_num | | |
51-
| ->string() | string | | |
52-
| ->uppercase() | uppercase | | |
53-
| ->lowercase() | lowercase | | |
54-
| ->regex() | regex:pattern | | |
55-
| ->hexColor() | hex_color | | |
56-
| ->json() | json | | |
57-
| ->url() | url or url:http,https | | |
58-
| ->uuid() | uuid | | |
59-
| ->ulid() | ulid | | |
60-
| ->timezone() | timezone | | |
61-
| ->date() | date | | |
62-
| ->dateFormat() | date_format | | |
63-
| ->dateEquals() | date_equals | | |
64-
| ->dateBefore() | before | | |
65-
| ->dateBeforeOrEqual() | before_or_equal | | |
66-
| ->dateAfter() | after | | |
67-
| ->dateAfterOrEqualToday() | after_or_equal:today | | |
68-
| ->dateAfterOrEquals() | after_or_equal | | |
69-
| ->ip() | ip | | |
70-
| ->ipv4() | ipv4 | | |
71-
| ->ipv6() | ipv6 | | |
72-
| ->macAddress() | mac_address | | |
31+
| **Methods** | **Laravel Rule** | **Methods** | **Rule** |
32+
|:-------------------------:|:---------------------:|:------------------------:|:--------------------------:|
33+
| Rule::required() | required | ->startsWith() | starts_with:foo,bar... |
34+
| Rule::nullable() | nullable | ->uppercaseFirstLetter() | new UppercaseFirstLetter() |
35+
| Rule::boolean() | boolean | ->size() | size |
36+
| Rule::rules() | custom rules | ->endsWith() | ends_with:foo,bar |
37+
| ->email() | email | ->doesntStartWith() | doesnt_start_with:foo,bar |
38+
| ->uniqueEmail() | unique:users,email | ->doesntEndWith() | doesnt_end_with:foo,bar |
39+
| ->min() | min | ->in() | in:foo,bar... |
40+
| ->max() | max | ->notIn() | not_in:foo,bar,baz... |
41+
| ->minDigits() | min_digits | | |
42+
| ->maxDigits() | max_digits | | |
43+
| ->integer() | integer | | |
44+
| ->numeric() | numeric | | |
45+
| ->digits() | digits:1 | | |
46+
| ->digitsBetween() | digits:1,4 | | |
47+
| ->decimal() | decimal | | |
48+
| ->alpha() | alpha | | |
49+
| ->alphaDash() | alpha_dash | | |
50+
| ->alphaNum() | alpha_num | | |
51+
| ->string() | string | | |
52+
| ->uppercase() | uppercase | | |
53+
| ->lowercase() | lowercase | | |
54+
| ->regex() | regex:pattern | | |
55+
| ->hexColor() | hex_color | | |
56+
| ->json() | json | | |
57+
| ->url() | url or url:http,https | | |
58+
| ->uuid() | uuid | | |
59+
| ->ulid() | ulid | | |
60+
| ->timezone() | timezone | | |
61+
| ->date() | date | | |
62+
| ->dateFormat() | date_format | | |
63+
| ->dateEquals() | date_equals | | |
64+
| ->dateBefore() | before | | |
65+
| ->dateBeforeOrEqual() | before_or_equal | | |
66+
| ->dateAfter() | after | | |
67+
| ->dateAfterOrEqualToday() | after_or_equal:today | | |
68+
| ->dateAfterOrEquals() | after_or_equal | | |
69+
| ->ip() | ip | | |
70+
| ->ipv4() | ipv4 | | |
71+
| ->ipv6() | ipv6 | | |
72+
| ->macAddress() | mac_address | | |
7373

7474
</div>
7575

@@ -78,7 +78,7 @@ return [
7878

7979
### Writing custom messages
8080

81-
```<?php
81+
```php
8282

8383
namespace App\Http\Requests;
8484

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Shergela\Validations\Enums;
4+
5+
enum DatetimeZoneAbbreviationEnum: string
6+
{
7+
public const AFRICA = 'Africa';
8+
public const AMERICA = 'America';
9+
public const ANTARCTICA = 'Antarctica';
10+
public const ARCTIC = 'Arctic';
11+
public const ASIA = 'Asia';
12+
public const ATLANTIC = 'Atlantic';
13+
public const AUSTRALIA = 'Australia';
14+
public const EUROPE = 'Europe';
15+
public const INDIAN = 'Indian';
16+
public const PACIFIC = 'Pacific';
17+
}

src/Enums/ValidationDateEnum.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ enum ValidationDateEnum: string
1818

1919
public const DATE_FORMAT = 'date_format:';
2020
public const TIMEZONE = 'timezone:';
21+
public const TIMEZONE_ALL = 'timezone:all';
2122
}

src/Enums/ValidationRegexEnum.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,19 @@ enum ValidationRegexEnum: string
2828
* Numbers
2929
*/
3030
public const NUMBERS = 'regex:/\pN/u';
31+
32+
/**
33+
* Separate integers by comma (1,2,3,4,5).
34+
*/
35+
public const SEPARATE_INTEGERS_BY_COMMA = "/^\d+(?:,\d+)*$/";
36+
37+
/**
38+
* Separate strings by comma. (ana,gustav,john).
39+
*/
40+
public const SEPARATE_STRINGS_BY_COMMA = "/^[a-z]+(?:,[a-z]+)*$/";
41+
42+
/**
43+
* Separate strings by underscore (ana_gustav_john).
44+
*/
45+
public const SEPARATE_STRINGS_BY_UNDERSCORE = "/^[a-z]+(?:_[a-z]+)*$/";
3146
}

src/Rules/LowercaseFirstLetter.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Shergela\Validations\Rules;
4+
5+
use Closure;
6+
use Illuminate\Contracts\Validation\ValidationRule;
7+
use Illuminate\Support\Str;
8+
9+
class LowercaseFirstLetter implements ValidationRule
10+
{
11+
/**
12+
* @param string $attribute
13+
* @param mixed $value
14+
* @param Closure $fail
15+
* @return void
16+
*/
17+
public function validate(string $attribute, mixed $value, Closure $fail): void
18+
{
19+
/** @var string $toString */
20+
$toString = $value;
21+
22+
if (is_numeric($toString)) {
23+
$fail('The :attribute must be a alphabetical string.');
24+
}
25+
26+
if (Str::lcfirst($toString) !== $value) {
27+
$fail('The first character of :attribute must be lowercase letter.');
28+
}
29+
}
30+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Shergela\Validations\Rules;
4+
5+
use Closure;
6+
use Illuminate\Contracts\Validation\ValidationRule;
7+
use Shergela\Validations\Enums\ValidationRegexEnum as Regex;
8+
9+
class SeparateIntegersByComma implements ValidationRule
10+
{
11+
/**
12+
* @param string $attribute
13+
* @param mixed $value
14+
* @param Closure $fail
15+
* @return void
16+
*/
17+
public function validate(string $attribute, mixed $value, Closure $fail): void
18+
{
19+
/** @var string $toString */
20+
$toString = $value;
21+
22+
if (! preg_match(pattern: Regex::SEPARATE_INTEGERS_BY_COMMA, subject: $toString)) {
23+
$fail("Please separate (:attribute) integer values by comma. Entered value: {$toString}");
24+
}
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Shergela\Validations\Rules;
4+
5+
use Closure;
6+
use Illuminate\Contracts\Validation\ValidationRule;
7+
use Shergela\Validations\Enums\ValidationRegexEnum as Regex;
8+
9+
class SeparateStringsByComma implements ValidationRule
10+
{
11+
/**
12+
* @param string $attribute
13+
* @param mixed $value
14+
* @param Closure $fail
15+
* @return void
16+
*/
17+
public function validate(string $attribute, mixed $value, Closure $fail): void
18+
{
19+
/** @var string $toString */
20+
$toString = $value;
21+
22+
if (! preg_match(pattern: Regex::SEPARATE_STRINGS_BY_COMMA, subject: $toString)) {
23+
$fail("Please separate (:attribute) values by comma. Entered value: {$toString}");
24+
}
25+
}
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Shergela\Validations\Rules;
4+
5+
use Closure;
6+
use Illuminate\Contracts\Validation\ValidationRule;
7+
use Shergela\Validations\Enums\ValidationRegexEnum as Regex;
8+
9+
class SeparateStringsByUnderscore implements ValidationRule
10+
{
11+
/**
12+
* @param string $attribute
13+
* @param mixed $value
14+
* @param Closure $fail
15+
* @return void
16+
*/
17+
public function validate(string $attribute, mixed $value, Closure $fail): void
18+
{
19+
/** @var string $toString */
20+
$toString = $value;
21+
22+
if (! preg_match(pattern: Regex::SEPARATE_STRINGS_BY_UNDERSCORE, subject: $toString)) {
23+
$fail("Please separate (:attribute) values by underscore. Entered value: {$toString}");
24+
}
25+
}
26+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
namespace Shergela\Validations\Rules;
4+
5+
use Closure;
6+
use DateTimeZone;
7+
use Illuminate\Contracts\Validation\ValidationRule;
8+
9+
class TimezoneRegionValidation implements ValidationRule
10+
{
11+
private ?string $message = null;
12+
13+
/**
14+
* @param array<string> $cities
15+
*/
16+
public function __construct(
17+
protected array $cities,
18+
protected int $timezoneGroupNumber,
19+
protected string $timezoneGroup,
20+
) {
21+
}
22+
23+
/**
24+
* @param string $attribute
25+
* @param mixed $value
26+
* @param Closure $fail
27+
* @return void
28+
*/
29+
public function validate(string $attribute, mixed $value, Closure $fail): void
30+
{
31+
/** @var string $toString */
32+
$toString = $value;
33+
34+
$toString = strtolower($toString);
35+
36+
$search = $this->timezoneGroup . '/' . $toString;
37+
38+
$timezonesList = $this->getTimezoneLists();
39+
40+
/**
41+
* Validate cities if is valid for time zone regions.
42+
*/
43+
if ($this->validateCities() === false) {
44+
$fail($this->message);
45+
return;
46+
};
47+
48+
$timezonesList = collect($timezonesList)->map(function ($value) {
49+
return strtolower($value);
50+
})->toArray();
51+
52+
if (! in_array($search, $timezonesList)) {
53+
$fail(
54+
sprintf(
55+
"The city name [:attribute] (%s) is not in the valid timezone for (%s) list.",
56+
ucfirst($toString),
57+
ucfirst($this->timezoneGroup)
58+
)
59+
);
60+
}
61+
}
62+
63+
/**
64+
* @return bool
65+
*/
66+
private function validateCities(): bool
67+
{
68+
foreach ($this->cities as $city) {
69+
if (! in_array($city, $this->getTimezoneLists())) {
70+
$this->message = sprintf(
71+
"This timezone [%s] is not in the valid timezone for [%s].",
72+
ucfirst($city),
73+
ucfirst($this->timezoneGroup)
74+
);
75+
return false;
76+
}
77+
}
78+
return true;
79+
}
80+
81+
/**
82+
* @return array<string>
83+
*/
84+
private function getTimezoneLists(): array
85+
{
86+
return collect(DateTimeZone::listIdentifiers($this->timezoneGroupNumber))->map(
87+
function ($value) {
88+
return strtolower($value);
89+
}
90+
)->toArray();
91+
}
92+
}

0 commit comments

Comments
 (0)