-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from SoftwarePunt/feat-validation-attributes
Model Validation
- Loading branch information
Showing
24 changed files
with
682 additions
and
27 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# Validation | ||
**Instarecord offers optional, built-in validation of model instances.** | ||
|
||
## Introduction | ||
|
||
### Setting constraints | ||
You can specify constraints by adding attributes to the model properties. | ||
|
||
```php | ||
<?php | ||
|
||
use Instarecord\Model; | ||
use SoftwarePunt\Instarecord\Attributes\FriendlyName;use SoftwarePunt\Instarecord\Attributes\MaxLength; | ||
use SoftwarePunt\Instarecord\Attributes\MinLength; | ||
|
||
class User extends Model | ||
{ | ||
#[Required] | ||
#[MinLength(3, "Your name is too short!")] | ||
public string $name; | ||
|
||
#[Required] | ||
#[MaxLength(255)] | ||
#[FriendlyName("E-mail address")] | ||
public string $email; | ||
} | ||
``` | ||
|
||
### Running validations | ||
⚠️ Validations are currently not run automatically when saving a model. You must call `validate()` manually. | ||
|
||
You can validate a model by simply calling `validate()` on it: | ||
|
||
```php | ||
$user = new User(); | ||
$user->name = "A"; | ||
$user->email = ""; | ||
$result = $user->validate(); | ||
|
||
if (!$result->ok) { | ||
foreach ($result->errors as $error) { | ||
echo $error->message . "\n"; | ||
} | ||
} | ||
``` | ||
|
||
The example above will output: | ||
|
||
``` | ||
Your name is too short! | ||
E-mail address is required. | ||
``` | ||
|
||
## Validation attributes | ||
|
||
Validation attributes live in the `Instarecord\Attributes` namespace. | ||
|
||
### `#[FriendlyName(string $friendlyName)]` | ||
|
||
Specifies a friendly name for the property. This is used in default error messages. | ||
|
||
If no friendly name is specified, the property name is used. | ||
|
||
### `#[Required]` | ||
|
||
The property is required and its value cannot be: | ||
|
||
- `null` | ||
- empty string | ||
- whitespace-only string | ||
- `false` | ||
- zero | ||
- empty array | ||
|
||
> {name} is required. | ||
### `#[MinLength(int $minLength, ?string $customError = null)]` | ||
|
||
Requires the property to be non-null, non-empty and at least `$minLength` characters long. | ||
|
||
> {name} must be at least {minLength} characters. | ||
### `#[MaxLength(int $maxLength, ?string $customError = null)]` | ||
|
||
Requires the property to be at most `$maxLength` characters long. | ||
|
||
> {name} can't be longer than {maxLength} characters. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace SoftwarePunt\Instarecord\Attributes; | ||
|
||
use Attribute; | ||
|
||
/** | ||
* Specifies a user-friendly name for a property, used in validation error messages. | ||
*/ | ||
#[Attribute(Attribute::TARGET_PROPERTY)] | ||
class FriendlyName | ||
{ | ||
public function __construct(public string $name) | ||
{ | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<?php | ||
|
||
namespace SoftwarePunt\Instarecord\Attributes; | ||
|
||
use Attribute; | ||
use SoftwarePunt\Instarecord\Validation\ValidationAttribute; | ||
use SoftwarePunt\Instarecord\Validation\ValidationResult; | ||
|
||
/** | ||
* Specifies the maximum length of a model property value. | ||
* | ||
* WIP: When used with migrations, this represents the maximum length of the column. | ||
*/ | ||
#[Attribute(Attribute::TARGET_PROPERTY)] | ||
class MaxLength extends ValidationAttribute | ||
{ | ||
public function __construct(public int $maxLength, public ?string $customError = null) | ||
{ | ||
} | ||
|
||
public function validate(string $name, mixed $value): ValidationResult | ||
{ | ||
if (empty($value)) | ||
// Do not validate null/empty values | ||
return ValidationResult::pass(); | ||
|
||
if (strlen($value) <= $this->maxLength) | ||
// Pass: The value is shorter than/equal to the maximum length | ||
return ValidationResult::pass(); | ||
|
||
return ValidationResult::fail( | ||
$this->customError ?? "{$name} can't be longer than {$this->maxLength} characters" | ||
); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
namespace SoftwarePunt\Instarecord\Attributes; | ||
|
||
use Attribute; | ||
use SoftwarePunt\Instarecord\Validation\ValidationAttribute; | ||
use SoftwarePunt\Instarecord\Validation\ValidationResult; | ||
|
||
/** | ||
* Specifies the minimum length of a model property value. | ||
*/ | ||
#[Attribute(Attribute::TARGET_PROPERTY)] | ||
class MinLength extends ValidationAttribute | ||
{ | ||
public function __construct(public int $minLength, public ?string $customError = null) | ||
{ | ||
} | ||
|
||
public function validate(string $name, mixed $value): ValidationResult | ||
{ | ||
if (!empty($value) && strlen($value) >= $this->minLength) | ||
// Pass: The value is not null/empty and is at least the minimum length | ||
return ValidationResult::pass(); | ||
|
||
return ValidationResult::fail( | ||
$this->customError ?? "{$name} must be at least {$this->minLength} characters" | ||
); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
namespace SoftwarePunt\Instarecord\Attributes; | ||
|
||
use Attribute; | ||
use SoftwarePunt\Instarecord\Validation\ValidationAttribute; | ||
use SoftwarePunt\Instarecord\Validation\ValidationResult; | ||
|
||
/** | ||
* Marks a model property as required (not null, empty or whitespace). | ||
*/ | ||
#[Attribute(Attribute::TARGET_PROPERTY)] | ||
class Required extends ValidationAttribute | ||
{ | ||
public function __construct(public ?string $customError = null) | ||
{ | ||
} | ||
|
||
public function validate(string $name, mixed $value): ValidationResult | ||
{ | ||
if ($value === null || $value === "" || (is_string($value) && trim($value) === "") | ||
|| $value === false || $value === 0 || (is_array($value) && empty($value))) | ||
return ValidationResult::fail($this->customError ?? "{$name} is required"); | ||
|
||
return ValidationResult::pass(); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
namespace SoftwarePunt\Instarecord\Attributes; | ||
|
||
use Attribute; | ||
|
||
/** | ||
* Specifies a custom name for a model's backing table. | ||
*/ | ||
#[Attribute(Attribute::TARGET_CLASS)] | ||
class TableName | ||
{ | ||
public function __construct(public string $name) | ||
{ | ||
} | ||
} |
Oops, something went wrong.