Last active
December 1, 2022 19:35
-
-
Save LegitDongo/2626ce323b8396349b30b5c4a544bca6 to your computer and use it in GitHub Desktop.
A validation rule for Laravel that sets min/max boundries based on the mysql column type. Excludes variable-length column types.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* this file is app/Providers/AppServiceProvider@boot | |
* | |
* adds the global "col" key for validators | |
* possible values are as follows: | |
* string types: | |
* `varchar`, `tinytext`, `text`, `mediumtext`, `longtext` | |
* NOTE: `varchar` assumes the default for Laravel, 255; don't use this if you use a specific column size | |
* | |
* number types (non-explicit assumes it's signed): | |
* `bit`, `bool`, `boolean`, | |
* `tinyint`, `signed_tinyint`, `unsigned_tinyint`, | |
* `smallint`, `signed_smallint`, `unsigned_smallint`, | |
* `mediumint`, `signed_mediumint`, `unsigned_mediumint`, | |
* `int`, `integer`, `signed_int`, `signed_integer`, `unsigned_int`, `unsigned_integer`, | |
* `bigint`, `signed_bigint`, `unsigned_bigint` | |
* | |
* usage with example; ripped out of https://laravel.com/docs/9.x/validation#quick-writing-the-validation-logic | |
* $validated = $request->validate([ | |
* 'title' => 'required|unique:posts|col:tinytext', | |
* 'body' => 'required|col:text', | |
* ]); | |
*/ | |
Validator::extend('col', function ($attribute, $value, $parameters, $validator) { | |
/** | |
* @var string $attribute | |
* @var string $value | |
* @var string[] $parameters | |
* @var \Illuminate\Validation\Validator $validator | |
*/ | |
if (count($parameters) < 1) { | |
throw new \InvalidArgumentException("Validation rule col requires at least 1 parameters."); | |
} | |
$textSizes = [ | |
'varchar' => 255, // assumes that the VARCHAR field accepted the default size, which is max pre MySQL 5.0.3 | |
'tinytext' => 255, | |
'text' => 65535, | |
'mediumtext' => 16777215, | |
'longtext' => 4294967295 | |
]; | |
$numberSizes = [ | |
'bit' => [0, 1], | |
'bool' => [0, 1], | |
'boolean' => [0, 1], | |
'tinyint' => [-128, 127], | |
'signed_tinyint' => [-128, 127], | |
'unsigned_tinyint' => [0, 255], | |
'smallint' => [-8388608, 8388607], | |
'signed_smallint' => [-8388608, 8388607], | |
'unsigned_smallint' => [0, 65535], | |
'mediumint' => [-8388608, 8388607], | |
'signed_mediumint' => [-8388608, 8388607], | |
'unsigned_mediumint' => [0, 16777215], | |
'int' => [-2147483648, 2147483647], | |
'signed_int' => [-2147483648, 2147483647], | |
'unsigned_int' => [0, 4294967295], | |
'integer' => [-2147483648, 2147483647], | |
'signed_integer' => [-2147483648, 2147483647], | |
'unsigned_integer' => [0, 4294967295], | |
'bigint' => ['-9223372036854775808', '9223372036854775807'], | |
'signed_bigint' => ['-9223372036854775808', '9223372036854775807'], | |
'unsigned_bigint' => [0, '18446744073709551615'], | |
]; | |
if (!isset($textSizes[$parameters[0]]) && !isset($numberSizes[$parameters[0]])) { | |
throw new \InvalidArgumentException( | |
'Validation rule col requires a valid mysql column type on field ' . $attribute | |
); | |
} | |
$min = $numberSizes[$parameters[0]][0] ?? 0; | |
$max = $numberSizes[$parameters[0]][1] ?? $textSizes[$parameters[0]]; | |
$validator->setCustomMessages([ | |
'col' => "The :attribute field requires the value to be between $min and $max" | |
. (isset($textSizes[$parameters[0]]) ? ' characters long' : '') | |
]); | |
if (isset($textSizes[$parameters[0]])) { | |
return mb_strlen($value) <= $textSizes[$parameters[0]]; | |
} | |
return $min <= $value && $max >= $value; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Instead of having a giant closure in your AppServiceProvider, you can also abstract it to a class and call it like the following:
Validator::extend('col', '\App\Rules\MysqlColumnLengthRule@validate')