mirror of
https://github.com/Respect/Validation.git
synced 2026-03-16 07:15:45 +01:00
Currently, the only way to handle when a validation fails is by `assert()`, which either throws an exception or doesn't. That means that every time a user wants to handle the results, they must use try-catch blocks, which may add some overhead. This commit introduces the `ResultQuery` class that wraps a `Result` object, providing an alternative to exception-based validation. This allows users to handle results directly without try-catch blocks. I’m taking a risky move here using the old method `validate()`, but I can’t think of a better name for this method.
133 lines
3.3 KiB
PHP
133 lines
3.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
namespace Respect\Validation;
|
|
|
|
use Respect\Validation\Message\ArrayFormatter;
|
|
use Respect\Validation\Message\Renderer;
|
|
use Respect\Validation\Message\StringFormatter;
|
|
use Stringable;
|
|
|
|
use function array_shift;
|
|
use function explode;
|
|
use function implode;
|
|
use function is_string;
|
|
|
|
final readonly class ResultQuery implements Stringable
|
|
{
|
|
/** @param array<string|int, mixed> $templates */
|
|
public function __construct(
|
|
private Result $result,
|
|
private Renderer $renderer,
|
|
private StringFormatter $messageFormatter,
|
|
private StringFormatter $fullMessageFormatter,
|
|
private ArrayFormatter $messagesFormatter,
|
|
private array $templates,
|
|
) {
|
|
}
|
|
|
|
public function findById(string $id): self|null
|
|
{
|
|
if ($this->result->id->value === $id) {
|
|
return $this;
|
|
}
|
|
|
|
foreach ($this->result->children as $child) {
|
|
$resultQuery = clone ($this, ['result' => $child]);
|
|
if ($child->id->value === $id) {
|
|
return $resultQuery;
|
|
}
|
|
|
|
return $resultQuery->findById($id);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function findByName(string $name): self|null
|
|
{
|
|
if ($this->result->name?->value === $name) {
|
|
return $this;
|
|
}
|
|
|
|
foreach ($this->result->children as $child) {
|
|
$resultQuery = clone ($this, ['result' => $child]);
|
|
if ($child->name?->value === $name) {
|
|
return $resultQuery;
|
|
}
|
|
|
|
return $resultQuery->findByName($name);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function findByPath(string|int $path): self|null
|
|
{
|
|
if ($this->result->path?->value === $path) {
|
|
return $this;
|
|
}
|
|
|
|
$paths = is_string($path) ? explode('.', $path) : [$path];
|
|
$currentPath = array_shift($paths);
|
|
|
|
foreach ($this->result->children as $child) {
|
|
if ($child->path?->value !== $currentPath) {
|
|
continue;
|
|
}
|
|
|
|
$resultQuery = clone ($this, ['result' => $child]);
|
|
if ($paths === []) {
|
|
return $resultQuery;
|
|
}
|
|
|
|
return $resultQuery->findByPath(is_string($path) ? implode('.', $paths) : $path);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function isValid(): bool
|
|
{
|
|
return $this->result->hasPassed;
|
|
}
|
|
|
|
public function toMessage(): string
|
|
{
|
|
if ($this->result->hasPassed) {
|
|
return '';
|
|
}
|
|
|
|
return $this->messageFormatter->format($this->result, $this->renderer, $this->templates);
|
|
}
|
|
|
|
public function toFullMessage(): string
|
|
{
|
|
if ($this->result->hasPassed) {
|
|
return '';
|
|
}
|
|
|
|
return $this->fullMessageFormatter->format($this->result, $this->renderer, $this->templates);
|
|
}
|
|
|
|
/** @return array<string|int, mixed> */
|
|
public function toArrayMessages(): array
|
|
{
|
|
if ($this->result->hasPassed) {
|
|
return [];
|
|
}
|
|
|
|
return $this->messagesFormatter->format($this->result, $this->renderer, $this->templates);
|
|
}
|
|
|
|
public function __toString(): string
|
|
{
|
|
return $this->toMessage();
|
|
}
|
|
}
|