Skip to content

Commit

Permalink
[feat] Get all validation messages.
Browse files Browse the repository at this point in the history
  • Loading branch information
warrickbayman committed Aug 27, 2023
1 parent 29f639d commit ff52bca
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 6 deletions.
9 changes: 7 additions & 2 deletions src/Result.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
public function __construct(
protected bool $outcome,
protected ?string $success = null,
protected ?string $failure = null
protected ?string $failure = null,
protected ?array $messages = null,
) {
}

Expand All @@ -23,8 +24,12 @@ public function failed(): bool
return $this->outcome !== true;
}

public function message(): ?string
public function message(): string|array|null
{
if ($this->messages) {
return $this->messages;
}

return $this->passed() ? $this->success : $this->failure;
}

Expand Down
13 changes: 12 additions & 1 deletion src/Validated.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public function property(string $property, string $rule = null): Result

if (! $rule) {
$filter = array_filter($result, fn (Result $result) => $result->failed());
return new Result(count($filter) === 0);
$messages = array_map(fn (Result $result) => $result->message(), $result);
return new Result(count($filter) === 0, messages: $messages);
}

if (! array_key_exists($rule, $result)) {
Expand All @@ -67,4 +68,14 @@ public function failed(): bool
{
return ! $this->passed();
}

public function messages(): array
{
$messages = [];
foreach ($this->properties as $property) {
$messages[$property->name] = $this->property($property->name)->message();
}

return $messages;
}
}
6 changes: 3 additions & 3 deletions src/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ public function __construct(protected mixed $source)
public function validate(): Validated
{
$properties = (new ReflectionClass($this->source))->getProperties(ReflectionProperty::IS_PUBLIC);
$errors = [];
$results = [];

foreach ($properties as $property) {
$errors[$property->getName()] = $this->validateProperty($property);
$results[$property->getName()] = $this->validateProperty($property);
}

return new Validated($properties, $errors);
return new Validated($properties, $results);
}

protected function validateProperty(ReflectionProperty $property): array
Expand Down
35 changes: 35 additions & 0 deletions tests/ObjectValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,41 @@
->and((string)$validated->property('name', Rules\Required::class))->toEqual('success message');
});

it('can get all validation messages for a property', function () {
$option = new class {
#[Rules\Required(success: 'Has email'), Rules\Email(failure: 'Not a valid email')]
public string $email = 'test@bad-email';
};

$validated = (new Validator($option))->validate();

expect($validated->property('email')->message())->toEqual([
Rules\Required::class => 'Has email',
Rules\Email::class => 'Not a valid email',
]);
});

it('can get all the validation messages for an object', function () {
$option = new class {
#[Rules\Required(failure: 'Name is required')]
public string $name = '';
#[Rules\Required(success: 'Has email'), Rules\Email(failure: 'Not a valid email')]
public string $email = 'test@bad-email';
};

$validated = (new Validator($option))->validate();

expect($validated->messages())->toEqual([
'name' => [
Rules\Required::class => 'Name is required',
],
'email' => [
Rules\Required::class => 'Has email',
Rules\Email::class => 'Not a valid email',
],
]);
});

it('can stop on a failed rule marked as last', function () {

$object = new class () {
Expand Down

0 comments on commit ff52bca

Please sign in to comment.