Validation rule EnumIsValidRule

This commit is contained in:
Jérémy Munsch 2021-03-17 00:52:03 +01:00
parent df8022c495
commit 7280504931
10 changed files with 167 additions and 4 deletions

View file

@ -9,6 +9,7 @@ All notable changes to `Enum` will be documented in this file.
## Version 0.0.2
### - Add
- Enum cast in Models
usage:
@ -23,6 +24,7 @@ All notable changes to `Enum` will be documented in this file.
## Version 0.1.0
### - Changed
- toArray Method now returns an array of BaseEnums
this is because php numeric string array indexes to int, this would break
origin enum values
@ -30,9 +32,22 @@ All notable changes to `Enum` will be documented in this file.
## Version 0.1.1
### Fixed
- fixed performances issue on toValues and toLabels
- Fixed performances issue on toValues and toLabels
## Version 0.1.2
### Changed
- changed toJson to output array with label and value
- Changed toJson to output array with label and value
## Version 0.1.3
### Added
- Validation rule EnumIsValidRule, the constructor needs a BaseEnum class
eg: new EnumIsValidRule(ArcadiaMailType::class)
### Fixed
- Unit tests with 0.1.2 changes

View file

@ -32,5 +32,12 @@
"psr-4": {
"Kwaadpepper\\Enum\\Tests\\": "tests"
}
},
"extra": {
"laravel": {
"providers": [
"Kwaadpepper\\Enum\\EnumServiceProvider"
]
}
}
}

4
resources/lang/en.json Normal file
View file

@ -0,0 +1,4 @@
{
"enum::enum.isNotValid": "The field :attribute is not valid, it has to be an integer or a string.",
"enum::enum.notInList": "The field :attribute has to be one of the followings: :values"
}

4
resources/lang/fr.json Normal file
View file

@ -0,0 +1,4 @@
{
"enum::enum.isNotValid": "Le champ :attribute n'est pas valide, il doit être un entier ou une chaine.",
"enum::enum.notInList": "Le champ :attribute doit être une des valeurs suivantes: :values"
}

View file

@ -268,8 +268,8 @@ abstract class BaseEnum implements JsonSerializable, UrlRoutable
public function jsonSerialize()
{
return [
'value' => $this->value,
'label' => $this->label
'label' => $this->label,
'value' => $this->value
];
}

View file

@ -0,0 +1,22 @@
<?php
namespace Kwaadpepper\Enum;
use Illuminate\Support\ServiceProvider;
class EnumServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadJsonTranslationsFrom(__DIR__ . '/../resources/lang', 'enum');
$this->publishes([
__DIR__ . '/../resources/lang' => resource_path('lang/vendor/enum'),
]);
}
}

View file

@ -0,0 +1,10 @@
<?php
namespace Kwaadpepper\Enum\Exceptions;
use Exception;
class UnknownEnumClass extends Exception
{
//
}

View file

@ -0,0 +1,42 @@
<?php
namespace Kwaadpepper\Enum\Rules;
use Illuminate\Contracts\Validation\Rule;
use Kwaadpepper\Enum\Exceptions\UnknownEnumClass;
abstract class BaseEnumRule implements Rule
{
/** @var string $enum */
protected $enumClass;
/**
* Create a new rule instance
* which validate the fact that a value is within an Enum
*
* @param string $enumClass
* @return void
*/
public function __construct(string $enumClass)
{
if (!class_exists($enumClass)) {
throw new UnknownEnumClass();
}
$this->enumClass = $enumClass;
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
abstract public function passes($attribute, $value): bool;
/**
* Get the validation error message.
*
* @return string
*/
abstract public function message(): string;
}

View file

@ -0,0 +1,50 @@
<?php
namespace Kwaadpepper\Enum\Rules;
use BadMethodCallException;
use TypeError;
class EnumIsValidRule extends BaseEnumRule
{
private $messageType = 0;
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value): bool
{
try {
// try cast to int if is int
$value = is_numeric($value) && floatval(intval($value)) === floatval($value) ? (int)$value : $value;
forward_static_call([$this->enumClass, 'make'], $value);
} catch (TypeError $e) {
$this->messageType = 1;
return false;
} catch (BadMethodCallException $e) {
$this->messageType = 2;
return false;
}
return true;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message(): string
{
switch ($this->messageType) {
case 1:
return trans('enum::enum.isNotValid');
case 2:
return trans('enum::enum.notInList', [
'values' => implode(',', forward_static_call([$this->enumClass, 'toValues']))
]);
}
}
}

View file

@ -2,6 +2,7 @@
namespace Kwaadpepper\Enum\Tests;
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
use Kwaadpepper\Enum\Tests\Enums\ContactFormCivility;
use Kwaadpepper\Enum\Tests\Enums\Days;
use Kwaadpepper\Enum\Tests\Enums\ForceStringsFromInteger;
@ -108,4 +109,12 @@ class EnumTest extends TestCase
$response->assertOk();
$response->assertExactJson([ForceStringsFromInteger::valueB()]);
}
public function testRules()
{
$rule = new EnumIsValidRule(Days::class);
$this->assertTrue($rule->passes('day', Days::mon()->value));
$this->assertFalse($rule->passes('day', 9999));
$this->assertFalse($rule->passes('day', Days::mon()));
}
}