├── .styleci.yml ├── src ├── Exceptions │ ├── NumberParityException.php │ ├── StringContainsException.php │ └── DomainWhitelistException.php ├── Rules │ ├── ExcludesHtml.php │ ├── IncludesHtml.php │ ├── UKMobilePhone.php │ ├── NoWhitespace.php │ ├── TitleCase.php │ ├── Honorific.php │ ├── Uppercase.php │ ├── Base64EncodedString.php │ ├── Coordinate.php │ ├── NumberParity.php │ ├── DomainRestrictedEmail.php │ ├── HexColourCode.php │ ├── StringContains.php │ └── StrongPassword.php ├── ValidationRulesServiceProvider.php ├── Rule.php └── Support │ └── Honorifics.php ├── LICENSE.md ├── composer.json ├── resources └── lang │ └── en │ └── messages.php └── README.md /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel 2 | 3 | disabled: 4 | - alpha_ordered_imports 5 | -------------------------------------------------------------------------------- /src/Exceptions/NumberParityException.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 20 | 21 | return strip_tags((string) $value) === $value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Rules/IncludesHtml.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 20 | 21 | return strip_tags((string) $value) !== $value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Rules/UKMobilePhone.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 19 | 20 | return preg_match("/^(\+44\s?7\d{3}|\(?07\d{3}\)?)\s?\d{3}\s?\d{3}$/", $value) === 1; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ValidationRulesServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadTranslationsFrom(__DIR__.'/../resources/lang/', 'f9web-validation-rules'); 13 | 14 | $this->publishes( 15 | [ 16 | __DIR__.'/../resources/lang' => resource_path('lang/vendor/f9web-validation-rules'), 17 | ] 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Rules/NoWhitespace.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 20 | 21 | if (null === $value) { 22 | return true; 23 | } 24 | 25 | return preg_match('/\s/', $value) === 0; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Rules/TitleCase.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 21 | 22 | if (! is_string($value)) { 23 | return false; 24 | } 25 | 26 | return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8') === (string) $value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Rules/Honorific.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 23 | 24 | $value = str_replace('.', '', strtolower($value)); 25 | 26 | return in_array($value, (new Honorifics())->toArray()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Rules/Uppercase.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 22 | 23 | if (! is_string($value)) { 24 | return false; 25 | } 26 | 27 | return (string) $value === mb_strtoupper($value, mb_detect_encoding($value)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Rules/Base64EncodedString.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 22 | 23 | $decoded = base64_decode($value, true); 24 | 25 | if ($decoded === false) { 26 | return false; 27 | } 28 | 29 | if ($value !== base64_encode($decoded)) { 30 | return false; 31 | } 32 | 33 | // false positives are possible, finally validate the expected characters ... 34 | return preg_match('/^[a-zA-Z0-9\/\r\n+]*={0,2}$/', $value) === 1; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Rules/Coordinate.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 25 | 26 | $parts = explode(',', $value); 27 | 28 | if ($parts === [] || ! isset($parts[1])) { 29 | return false; 30 | } 31 | 32 | return preg_match( 33 | '/^[-]?(([0-8]?[0-9])\.(\d+))|(90(\.0+)?),[-]?((((1[0-7][0-9])|([0-9]?[0-9]))\.(\d+))|180(\.0+)?)$/', 34 | trim($parts[0]).','.trim($parts[1]) 35 | ) !== 0; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) F9WebLtd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/Rule.php: -------------------------------------------------------------------------------- 1 | getMessageKey(), 25 | [ 26 | 'attribute' => $this->getAttribute(), 27 | ] 28 | ); 29 | } 30 | 31 | /** 32 | * @return string 33 | */ 34 | public function getAttribute(): string 35 | { 36 | return $this->attribute; 37 | } 38 | 39 | /** 40 | * @param string $attribute 41 | */ 42 | public function setAttribute(string $attribute): void 43 | { 44 | $this->attribute = $attribute; 45 | } 46 | 47 | /** 48 | * @return string 49 | */ 50 | public function getMessageKey(): string 51 | { 52 | $calledClassName = class_basename(get_called_class()); 53 | 54 | return Str::slug(Str::snake($calledClassName)); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "f9webltd/laravel-validation-rules", 3 | "description": "A collection of useful Laravel validation rules", 4 | "keywords": [ 5 | "laravel", 6 | "laravel validation rules", 7 | "laravel validation", 8 | "custom laravel validation", 9 | "laravel request validation" 10 | ], 11 | "homepage": "https://github.com/f9webltd/laravel-validation-rules", 12 | "license": "MIT", 13 | "authors": [ 14 | { 15 | "name": "Rob Allport", 16 | "email": "rob@f9web.co.uk", 17 | "homepage": "https://www.f9web.co.uk", 18 | "role": "Developer" 19 | } 20 | ], 21 | "require": { 22 | "php": "^7.2", 23 | "ext-mbstring": "*", 24 | "illuminate/contracts": "5.8.* || ^6.0 || ^7.0 || ^8.0", 25 | "illuminate/support": "5.8.* || ^6.0 || ^7.0 || ^8.0" 26 | }, 27 | "require-dev": { 28 | "orchestra/testbench": ">=3.8", 29 | "phpunit/phpunit": "^7.0|^8.0" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "F9Web\\ValidationRules\\": "src" 34 | } 35 | }, 36 | "autoload-dev": { 37 | "psr-4": { 38 | "F9Web\\ValidationRules\\Tests\\": "tests" 39 | } 40 | }, 41 | "scripts": { 42 | "test": "vendor/bin/phpunit", 43 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 44 | }, 45 | "config": { 46 | "sort-packages": true 47 | }, 48 | "extra": { 49 | "laravel": { 50 | "providers": [ 51 | "F9Web\\ValidationRules\\ValidationRulesServiceProvider" 52 | ] 53 | } 54 | }, 55 | "minimum-stability": "dev", 56 | "prefer-stable": true 57 | } 58 | -------------------------------------------------------------------------------- /src/Support/Honorifics.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 26 | 27 | if (filter_var($value, FILTER_VALIDATE_INT) === false) { 28 | return false; 29 | } 30 | 31 | if (null === $this->mode) { 32 | throw new NumberParityException('Ensure the "odd()" or "even()" methods are called'); 33 | } 34 | 35 | return $this->mode === 'odd' 36 | ? (int) $value % 2 !== 0 37 | : (int) $value % 2 === 0; 38 | } 39 | 40 | /** 41 | * @return $this 42 | */ 43 | public function odd(): self 44 | { 45 | $this->mode = 'odd'; 46 | 47 | return $this; 48 | } 49 | 50 | /** 51 | * @return $this 52 | */ 53 | public function even(): self 54 | { 55 | $this->mode = 'even'; 56 | 57 | return $this; 58 | } 59 | 60 | /** 61 | * @return string 62 | */ 63 | public function message(): string 64 | { 65 | return __( 66 | 'f9web-validation-rules::messages.'.$this->getMessageKey().'.'.$this->mode, 67 | [ 68 | 'attribute' => $this->getAttribute(), 69 | ] 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /resources/lang/en/messages.php: -------------------------------------------------------------------------------- 1 | 'The :attribute field must only contain uppercase characters', 5 | 'title-case' => 'The :attribute must be in title case form', 6 | 'domain-restricted-email' => 'The :attribute must be an email address ending with any of the following :plural: :domains', 7 | 'excludes-html' => 'The :attribute contains html', 8 | 'includes-html' => 'The :attribute must contain html', 9 | 'string-contains' => [ 10 | 'strict' => 'The :attribute must contain all of the following phrases: :phrases', 11 | 'loose' => 'The :attribute must contain at least one of the following phrases: :phrases', 12 | ], 13 | 'hex-colour-code' => [ 14 | 'base' => 'The :attribute must be a valid :length length hex colour code', 15 | 'prefix' => ', prefixed with the "#" symbol', 16 | ], 17 | 'honorific' => 'The :attribute must be a valid honorific', 18 | 'coordinate' => 'The :attribute must be a valid set of comma separated coordinates i.e. 27.666530,-97.367170', 19 | 'no-whitespace' => 'The :attribute cannot contain spaces', 20 | 'strong-password' => [ 21 | 'base' => 'The :attribute has failed the security checks and must be', 22 | 'min' => 'at least :length characters long', 23 | 'uppercase' => 'include an uppercase letter', 24 | 'lowercase' => 'include a lowercase letter', 25 | 'numbers' => 'include numbers', 26 | 'special' => 'include at least one special character (:characters)', 27 | ], 28 | 'u-k-mobile-phone' => 'The :attribute must be a valid UK mobile number', 29 | 'base64-encoded-string' => 'The :attribute must be a valid base64 encoded string', 30 | 'number-parity' => [ 31 | 'even' => 'The :attribute must be an even number', 32 | 'odd' => 'The :attribute must be an odd number', 33 | ], 34 | ]; 35 | -------------------------------------------------------------------------------- /src/Rules/DomainRestrictedEmail.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 30 | 31 | if ($this->validDomains === []) { 32 | throw new DomainWhitelistException('Zero domains have been whitelisted using the "validDomains()" method'); 33 | } 34 | 35 | if (! filter_var($value, FILTER_VALIDATE_EMAIL)) { 36 | return false; 37 | } 38 | 39 | $domain = (string) explode('@', $value)[1]; 40 | 41 | return in_array($domain, $this->validDomains); 42 | } 43 | 44 | /** 45 | * @param array $domains 46 | * @return self 47 | */ 48 | public function validDomains(array $domains): self 49 | { 50 | $this->validDomains = $domains; 51 | 52 | return $this; 53 | } 54 | 55 | /** 56 | * @return string 57 | */ 58 | public function message(): string 59 | { 60 | return __( 61 | 'f9web-validation-rules::messages.'.$this->getMessageKey(), 62 | [ 63 | 'attribute' => $this->getAttribute(), 64 | 'plural' => Str::plural('domain', count($this->validDomains)), 65 | 'domains' => implode( 66 | ', ', 67 | array_map( 68 | function ($domain) { 69 | return '@'.$domain; 70 | }, 71 | $this->validDomains 72 | ) 73 | ), 74 | ] 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Rules/HexColourCode.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 28 | 29 | if ($this->includePrefix && ! Str::startsWith($value, '#')) { 30 | return false; 31 | } 32 | 33 | $pattern = $this->forceSixDigitCode 34 | ? '/^#([a-fA-F0-9]{6})$/' 35 | : '/^#([a-fA-F0-9]{3})$/'; 36 | 37 | return (bool) preg_match($pattern, $value); 38 | } 39 | 40 | /** 41 | * @return $this 42 | */ 43 | public function longFormat(): self 44 | { 45 | $this->forceSixDigitCode = true; 46 | 47 | return $this; 48 | } 49 | 50 | /** 51 | * @return $this 52 | */ 53 | public function shortFormat(): self 54 | { 55 | $this->forceSixDigitCode = false; 56 | 57 | return $this; 58 | } 59 | 60 | /** 61 | * @return $this 62 | */ 63 | public function withPrefix(): self 64 | { 65 | $this->includePrefix = true; 66 | 67 | return $this; 68 | } 69 | 70 | /** 71 | * @return $this 72 | */ 73 | public function withoutPrefix(): self 74 | { 75 | $this->includePrefix = false; 76 | 77 | return $this; 78 | } 79 | 80 | /** 81 | * @return string 82 | */ 83 | public function message(): string 84 | { 85 | $key = 'f9web-validation-rules::messages.'.$this->getMessageKey(); 86 | 87 | $message = __( 88 | $key.'.base', 89 | [ 90 | 'attribute' => $this->getAttribute(), 91 | 'length' => $this->forceSixDigitCode ? 6 : 3, 92 | ] 93 | ); 94 | 95 | if ($this->includePrefix) { 96 | return $message.__($key.'.prefix'); 97 | } 98 | 99 | return $message; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Rules/StringContains.php: -------------------------------------------------------------------------------- 1 | setAttribute($attribute); 32 | 33 | if ($this->phrases === []) { 34 | throw new StringContainsException('Zero phrases have been whitelisted using the "phrases()" method'); 35 | } 36 | 37 | $matched = collect($this->phrases)->reject( 38 | function ($phrase) use ($value) { 39 | return ! Str::contains($value, $phrase); 40 | } 41 | ); 42 | 43 | if ($this->mustContainAllPhrases) { 44 | return Str::containsAll($value, $this->phrases); 45 | } 46 | 47 | return $matched->isNotEmpty(); 48 | } 49 | 50 | /** 51 | * @param array $phrases 52 | * @return self 53 | */ 54 | public function phrases(array $phrases): self 55 | { 56 | $this->phrases = $phrases; 57 | 58 | return $this; 59 | } 60 | 61 | /** 62 | * @return $this 63 | */ 64 | public function strictly(): self 65 | { 66 | $this->mustContainAllPhrases = true; 67 | 68 | return $this; 69 | } 70 | 71 | /** 72 | * @return $this 73 | */ 74 | public function loosely(): self 75 | { 76 | $this->mustContainAllPhrases = false; 77 | 78 | return $this; 79 | } 80 | 81 | /** 82 | * @return string 83 | */ 84 | public function message(): string 85 | { 86 | $key = sprintf( 87 | 'f9web-validation-rules::messages.%s.%s', 88 | $this->getMessageKey(), 89 | $this->mustContainAllPhrases ? 'strict' : 'loose' 90 | ); 91 | 92 | return __( 93 | $key, 94 | [ 95 | 'attribute' => $this->getAttribute(), 96 | 'phrases' => implode( 97 | ', ', 98 | array_map( 99 | function ($phrase) { 100 | return '"'.$phrase.'"'; 101 | }, 102 | $this->phrases 103 | ) 104 | ), 105 | ] 106 | ); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Rules/StrongPassword.php: -------------------------------------------------------------------------------- 1 | '; 19 | 20 | /** @var bool */ 21 | protected $mustIncludeUppercaseCharacters = true; 22 | 23 | /** @var bool */ 24 | protected $mustIncludeLowercaseCharacters = true; 25 | 26 | /** @var bool */ 27 | protected $mustIncludeSpecialCharacters = false; 28 | 29 | /** @var bool */ 30 | protected $mustIncludeNumbers = true; 31 | 32 | /** 33 | * @param string $attribute 34 | * @param mixed $value 35 | * @return bool 36 | */ 37 | public function passes($attribute, $value): bool 38 | { 39 | $this->setAttribute($attribute); 40 | 41 | if ( 42 | $this->mustIncludeUppercaseCharacters && 43 | preg_match_all('/[A-Z]/', $value, $o) === 0 44 | ) { 45 | return false; 46 | } 47 | 48 | if ( 49 | $this->mustIncludeLowercaseCharacters && 50 | preg_match_all('/[a-z]/', $value, $o) === 0 51 | ) { 52 | return false; 53 | } 54 | 55 | if ( 56 | $this->mustIncludeSpecialCharacters && 57 | preg_match_all('/['.$this->specialCharacters.']/', $value, $o) === 0 58 | ) { 59 | return false; 60 | } 61 | 62 | if ( 63 | $this->mustIncludeNumbers && 64 | preg_match_all('/[0-9]/', $value, $o) === 0 65 | ) { 66 | return false; 67 | } 68 | 69 | if (mb_strlen($value, 'UTF-8') < $this->minCharacters) { 70 | return false; 71 | } 72 | 73 | return true; 74 | } 75 | 76 | /** 77 | * @param int $min 78 | * @return self 79 | */ 80 | public function min(int $min): self 81 | { 82 | $this->minCharacters = $min; 83 | 84 | return $this; 85 | } 86 | 87 | /** 88 | * @param bool $flag 89 | * @return $this 90 | */ 91 | public function forceUppercaseCharacters(bool $flag = true): self 92 | { 93 | $this->mustIncludeUppercaseCharacters = $flag; 94 | 95 | return $this; 96 | } 97 | 98 | /** 99 | * @param bool $flag 100 | * @return self 101 | */ 102 | public function forceLowercaseCharacters(bool $flag = true): self 103 | { 104 | $this->mustIncludeLowercaseCharacters = $flag; 105 | 106 | return $this; 107 | } 108 | 109 | /** 110 | * @param bool $flag 111 | * @return self 112 | */ 113 | public function forceNumbers(bool $flag = true): self 114 | { 115 | $this->mustIncludeNumbers = $flag; 116 | 117 | return $this; 118 | } 119 | 120 | /** 121 | * @param bool $flag 122 | * @return self 123 | */ 124 | public function forceSpecialCharacters(bool $flag = true): self 125 | { 126 | $this->mustIncludeSpecialCharacters = $flag; 127 | 128 | return $this; 129 | } 130 | 131 | /** 132 | * @param string $characters 133 | * @return self 134 | */ 135 | public function withSpecialCharacters(string $characters): self 136 | { 137 | $this->forceSpecialCharacters(); 138 | $this->specialCharacters = $characters; 139 | 140 | return $this; 141 | } 142 | 143 | /** 144 | * @return self 145 | */ 146 | public function reset(): self 147 | { 148 | $this->minCharacters = 8; 149 | $this->mustIncludeSpecialCharacters = false; 150 | $this->mustIncludeNumbers = false; 151 | $this->mustIncludeLowercaseCharacters = false; 152 | $this->mustIncludeUppercaseCharacters = false; 153 | 154 | return $this; 155 | } 156 | 157 | /** 158 | * @return string 159 | */ 160 | public function message(): string 161 | { 162 | $key = 'f9web-validation-rules::messages.'.$this->getMessageKey(); 163 | 164 | $message = []; 165 | 166 | $message[] = __( 167 | $key.'.base', 168 | [ 169 | 'attribute' => $this->getAttribute(), 170 | ] 171 | ); 172 | 173 | if ($this->minCharacters > 0) { 174 | $message[] = __( 175 | $key.'.min', 176 | [ 177 | 'length' => $this->minCharacters, 178 | ] 179 | ); 180 | } 181 | 182 | if ($this->mustIncludeUppercaseCharacters > 0) { 183 | $message[] = __($key.'.uppercase'); 184 | } 185 | 186 | if ($this->mustIncludeLowercaseCharacters > 0) { 187 | $message[] = __($key.'.lowercase'); 188 | } 189 | 190 | if ($this->mustIncludeNumbers > 0) { 191 | $message[] = __($key.'.numbers'); 192 | } 193 | 194 | if ($this->mustIncludeSpecialCharacters > 0) { 195 | $message[] = __( 196 | $key.'.special', 197 | [ 198 | 'characters' => $this->specialCharacters, 199 | ] 200 | ); 201 | } 202 | 203 | return implode(', ', $message); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Latest Stable Version](https://img.shields.io/packagist/v/f9webltd/laravel-validation-rules)](https://packagist.org/packages/f9webltd/laravel-validation-rules) 2 | [![Scrutinizer coverage (GitHub/BitBucket)](https://img.shields.io/scrutinizer/coverage/g/f9webltd/laravel-validation-rules)]() 3 | [![Scrutinizer code quality (GitHub/Bitbucket)](https://img.shields.io/scrutinizer/quality/g/f9webltd/laravel-validation-rules)]() 4 | [![Build Status](https://travis-ci.org/f9webltd/laravel-validation-rules.svg)](https://travis-ci.org/f9webltd/laravel-validation-rules) 5 | [![StyleCI Status](https://github.styleci.io/repos/266997689/shield)](https://github.styleci.io/repos/266997689) 6 | [![License](https://poser.pugx.org/f9webltd/laravel-validation-rules/license)](https://packagist.org/packages/f9webltd/laravel-validation-rules) 7 | 8 | # Useful Laravel Validation Rules 9 | 10 | A collection of useful Laravel validation rules. 11 | 12 | ## Requirements 13 | 14 | PHP >= 7.2, Laravel `>=5.8 | 6.x | 7.x | 8.x`. 15 | 16 | ## Installation 17 | 18 | ``` bash 19 | composer require f9webltd/laravel-validation-rules 20 | ``` 21 | 22 | To publish the package validation message translations: 23 | 24 | ``` bash 25 | php artisan vendor:publish --provider="F9Web\ValidationRules\ValidationRulesServiceProvider" 26 | ``` 27 | 28 | Published translations are available at `resources/lang/vendor/f9web-validation-rules/messages.php`. 29 | 30 | ## Usage 31 | 32 | As discussed in the official [Laravel documentation](https://laravel.com/docs/master/validation#using-rule-objects), import the required rule whenever required: 33 | 34 | ```php 35 | use F9Web\ValidationRules\Rules\TitleCase; 36 | 37 | // ... 38 | 39 | $request->validate([ 40 | 'team' => ['required', new TitleCase()], 41 | ]); 42 | ``` 43 | 44 | Alternatively use the rule directly with a [Laravel form request object](https://laravel.com/docs/7.x/validation#form-request-validation) 45 | 46 | ## Available rules 47 | 48 | - [`Base64EncodedString`](#base64encodedstring) 49 | - [`Coordinate`](#coordinate) 50 | - [`DomainRestrictedEmail`](#domainrestrictedemail) 51 | - [`ExcludesHtml`](#excludeshtml) 52 | - [`HexColourCode`](#hexcolourcode) 53 | - [`Honorific`](#honorific) 54 | - [`IncludesHtml`](#includeshtml) 55 | - [`NoWhitespace`](#nowhitespace) 56 | - [`NumberParity`](#numberparity) 57 | - [`StringContains`](#stringcontains) 58 | - [`StrongPassword`](#strongpassword) 59 | - [`TitleCase`](#titlecase) 60 | - [`UKMobilePhone`](#ukmobilephone) 61 | - [`Uppercase`](#uppercase) 62 | 63 | ### `Base64EncodedString` 64 | 65 | Ensure the passed attribute is a valid base 64 encoded string. 66 | 67 | ### `Coordinate` 68 | 69 | Ensure the passed attribute is a valid comma separated Latitude and Longitude string. For example: `51.507877,-0.087732`. 70 | 71 | ### `DomainRestrictedEmail` 72 | 73 | Ensure the passed email in question is part of the provided whitelist of domains. 74 | 75 | For instance, to ensure the given email domain is `f9web.co.uk` or `laravel.com`: 76 | 77 | ```php 78 | use F9Web\ValidationRules\Rules\DomainRestrictedEmail; 79 | 80 | // ... 81 | 82 | $request->validate([ 83 | 'email' => [ 84 | 'required', 85 | (new DomainRestrictedEmail())->validDomains([ 86 | 'f9web.co.uk', 87 | 'laravel.com', 88 | ]), 89 | ], 90 | ]); 91 | ``` 92 | 93 | The validation message will include the list of whitelisted domains based upon the provided configuration. 94 | 95 | ### `ExcludesHtml` 96 | 97 | Ensure the passed attribute does not contain HTML. 98 | 99 | ### `HexColourCode` 100 | 101 | Ensure the passed attribute is a valid hex colour code (three of six characters in length), optionally validating the presence of the `#` prefix. 102 | 103 | Minimum usage example to validate a short length code with the prefix i.e. `#fff`: 104 | 105 | ```php 106 | use F9Web\ValidationRules\Rules\HexColourCode; 107 | 108 | (new HexColourCode()); 109 | ``` 110 | 111 | Extended usage example to validate a long length code , omitting prefix i.e. `cc0000`: 112 | 113 | ```php 114 | use F9Web\ValidationRules\Rules\HexColourCode; 115 | 116 | (new HexColourCode())->withoutPrefix()->longFormat(); 117 | ``` 118 | 119 | ### `Honorific` 120 | 121 | Ensure the passed attribute is a valid honorific, omitting appended dots. The list of valid honorifics is available [here](src/Support/Honorifics.php). 122 | 123 | ### `IncludesHtml` 124 | 125 | Ensure the passed attribute contains HTML. 126 | 127 | ### `NoWhitespace` 128 | 129 | Ensure the passed attribute contains no whitespace. 130 | 131 | ### `NumberParity` 132 | 133 | Validate the number parity. 134 | 135 | An odd number: 136 | 137 | ```php 138 | use F9Web\ValidationRules\Rules\NumberParity; 139 | 140 | // ... 141 | 142 | $request->validate([ 143 | 'amount' => [ 144 | 'required', 145 | (new NumberParity())->odd(), 146 | ], 147 | ]); 148 | ``` 149 | 150 | An even number: 151 | 152 | ```php 153 | use F9Web\ValidationRules\Rules\NumberParity; 154 | 155 | // ... 156 | 157 | $request->validate([ 158 | 'amount' => [ 159 | 'required', 160 | (new NumberParity())->even(), 161 | ], 162 | ]); 163 | ``` 164 | 165 | ### `StringContains` 166 | 167 | Ensure the given attribute contains the provided strings. 168 | 169 | Minimum usage example to ensure the attribute in question contains the string `php` or `laravel`: 170 | 171 | ```php 172 | use F9Web\ValidationRules\Rules\StringContains; 173 | 174 | // ... 175 | 176 | $request->validate([ 177 | 'description' => [ 178 | 'required', 179 | (new StringContains())->phrases([ 180 | 'laravel', 181 | 'php', 182 | ]), 183 | ], 184 | ]); 185 | ``` 186 | 187 | Optionally force the string to contain *all* provided phrases: 188 | 189 | ```php 190 | use F9Web\ValidationRules\Rules\StringContains; 191 | 192 | // ... 193 | 194 | $request->validate([ 195 | 'description' => [ 196 | 'required', 197 | (new StringContains())->phrases([ 198 | 'laravel', 199 | 'php', 200 | ])->strictly(), 201 | ], 202 | ]); 203 | ``` 204 | The validation message will include the list phrases based upon the provided configuration. 205 | 206 | ### `StrongPassword` 207 | 208 | Ensure the given attribute matches the provided conditions. 209 | 210 | Minimum usage example to ensure the attribute: 211 | 212 | - is a minimum of eight characters in length 213 | - contains upper and lowercase characters 214 | - contains at least one number 215 | 216 | ```php 217 | use F9Web\ValidationRules\Rules\StrongPassword; 218 | 219 | // ... 220 | 221 | $request->validate([ 222 | 'password' => [ 223 | 'required', 224 | (new StrongPassword()), 225 | ], 226 | ]); 227 | ``` 228 | 229 | Additional methods are available. 230 | 231 | ```php 232 | use F9Web\ValidationRules\Rules\StrongPassword; 233 | 234 | // ... 235 | 236 | $request->validate([ 237 | 'password' => [ 238 | 'required', 239 | (new StrongPassword()) 240 | ->forceUppercaseCharacters() 241 | ->forceLowercaseCharacters(false) 242 | ->forceNumbers() 243 | ->forceSpecialCharacters() 244 | // ->withSpecialCharacters('£$*%^'), 245 | ], 246 | ]); 247 | ``` 248 | 249 | The default special characters are `!@#$%^&*()\-_=+{};:,<."£~?|>`. Optionally the `withSpecialCharacters()` method can be used to define a custom list. 250 | 251 | ### `TitleCase` 252 | 253 | Ensure the provided attribute is [title case](https://laravel.com/docs/7.x/helpers#method-title-case). 254 | 255 | ### `UKMobilePhone` 256 | 257 | Ensure the provided attribute is a valid UK mobile telephone number. 258 | 259 | ### `Uppercase` 260 | 261 | Ensure the provided attribute is entirely uppercase. 262 | 263 | ## Contribution 264 | 265 | Any ideas are welcome. Feel free to submit any issues or pull requests. 266 | 267 | ## Testing 268 | 269 | ``` bash 270 | composer test 271 | ``` 272 | 273 | ## Security 274 | 275 | If you discover any security related issues, please email rob@f9web.co.uk instead of using the issue tracker. 276 | 277 | ## Credits 278 | 279 | - [Rob Allport](https://github.com/ultrono) 280 | 281 | ## License 282 | 283 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 284 | --------------------------------------------------------------------------------