Skip to content

Commit 46bcda9

Browse files
authored
Merge pull request #11 from arifszn/feat/rule-username
feat: rule username
2 parents 3622713 + de927ca commit 46bcda9

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public function rules()
5555
- [`Hash`](#hash)
5656
- [`Image URL`](#imageurl)
5757
- [`Phone`](#phone)
58+
- [`Username`](#username)
5859
- [`Without Spaces`](#withoutspaces)
5960

6061

@@ -262,6 +263,26 @@ public function rules()
262263
}
263264
```
264265

266+
### `Username`
267+
268+
The field under validation must be a valid username.
269+
270+
- starts with a letter (alpha)
271+
- only alpha-numeric (a-z, A-Z, 0-9), underscore, minus and dot
272+
- multiple underscores, minus and are not allowed (-- or __ or ..)
273+
- underscores, minus and dot are not allowed at the beginning or end
274+
275+
```php
276+
use Arifszn\AdvancedValidation\Rules\Username;
277+
278+
public function rules()
279+
{
280+
return [
281+
'username' => [new Username()],
282+
];
283+
}
284+
```
285+
265286
### `WithoutSpaces`
266287

267288
The field under validation must not contain spaces.

resources/lang/en/validation.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@
1515
'hash' => 'The :attribute must be a hash of :algorithm algorithm.',
1616
'image_url' => 'The :attribute must be a valid image URL.',
1717
'phone' => 'The :attribute must be a valid phone number.',
18+
'username' => 'The :attribute must be a valid username.',
1819
'without_spaces' => 'The :attribute must not contain spaces.',
1920
];

src/Rules/Username.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Arifszn\AdvancedValidation\Rules;
4+
5+
use Illuminate\Contracts\Validation\Rule;
6+
7+
/**
8+
* The field under validation must be a valid username.
9+
*
10+
* - starts with a letter (alpha)
11+
* - only alpha-numeric (a-z, A-Z, 0-9), underscore, minus and dot
12+
* - multiple underscores, minus and are not allowed (-- or __ or ..)
13+
* - underscores, minus and dot are not allowed at the beginning or end
14+
*
15+
* @package Arifszn\AdvancedValidation\Rules
16+
*/
17+
class Username implements Rule
18+
{
19+
/**
20+
* @var string
21+
*/
22+
private $errorMessage;
23+
24+
/**
25+
* Create a new rule instance.
26+
*
27+
* @param string|null $errorMessage Custom error message.
28+
* @return void
29+
*/
30+
public function __construct(string $errorMessage = null)
31+
{
32+
$this->errorMessage = $errorMessage;
33+
}
34+
35+
/**
36+
* Determine if the validation rule passes.
37+
*
38+
* @param string $attribute
39+
* @param mixed $value
40+
* @return bool
41+
*/
42+
public function passes($attribute, $value)
43+
{
44+
return preg_match('/^[a-z][a-z0-9]*(?:[_\-\.][a-z0-9]+)*$/i', $value);
45+
}
46+
47+
/**
48+
* Get the validation error message.
49+
*
50+
* @return string
51+
*/
52+
public function message()
53+
{
54+
return $this->errorMessage ? $this->errorMessage : trans('advancedValidation::validation.username');
55+
}
56+
}

tests/Rules/UsernameTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace Arifszn\AdvancedValidation\Tests\Rules;
4+
5+
use Arifszn\AdvancedValidation\Rules\Username;
6+
use Arifszn\AdvancedValidation\Tests\TestCase;
7+
8+
class UsernameTest extends TestCase
9+
{
10+
/**
11+
* @dataProvider provider
12+
*/
13+
public function testValidation($result, $value)
14+
{
15+
$this->assertEquals($result, (new Username())->passes('foo', $value));
16+
}
17+
18+
public function provider()
19+
{
20+
return [
21+
[true, 'john'],
22+
[true, 'john.doe'],
23+
[true, 'john_doe'],
24+
[true, 'john-doe'],
25+
[true, 'john.doe.123'],
26+
[true, 'john123'],
27+
[true, 'john_123'],
28+
[true, 'john-123'],
29+
30+
[false, '_john'],
31+
[false, '-john'],
32+
[false, '.john'],
33+
[false, 'john_'],
34+
[false, 'john-'],
35+
[false, 'john.'],
36+
[false, '_john_'],
37+
[false, 'john__doe'],
38+
[false, 'john--doe'],
39+
[false, 'john..doe'],
40+
[false, '123'],
41+
[false, '123.john'],
42+
[false, '&nbsp;'],
43+
[false, 'a b c'],
44+
[false, 'foobar'],
45+
[false, '😀'],
46+
];
47+
}
48+
}

0 commit comments

Comments
 (0)