Skip to content

Commit

Permalink
Update the validation engine of composite-based rules
Browse files Browse the repository at this point in the history
Signed-off-by: Henrique Moody <[email protected]>
  • Loading branch information
henriquemoody committed Feb 22, 2024
1 parent 41245f6 commit f1b6f0c
Show file tree
Hide file tree
Showing 10 changed files with 170 additions and 509 deletions.
121 changes: 0 additions & 121 deletions library/Rules/AbstractComposite.php

This file was deleted.

41 changes: 1 addition & 40 deletions library/Rules/AllOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

namespace Respect\Validation\Rules;

use Respect\Validation\Attributes\ExceptionClass;
use Respect\Validation\Exceptions\NestedValidationException;
use Respect\Validation\Message\Template;
use Respect\Validation\Result;
use Respect\Validation\Rule;
Expand All @@ -20,7 +18,6 @@
use function array_reduce;
use function count;

#[ExceptionClass(NestedValidationException::class)]
#[Template(
'These rules must pass for {{name}}',
'These rules must not pass for {{name}}',
Expand All @@ -31,7 +28,7 @@
'None of these rules must pass for {{name}}',
self::TEMPLATE_NONE,
)]
final class AllOf extends AbstractComposite
final class AllOf extends Composite
{
public const TEMPLATE_NONE = '__none__';
public const TEMPLATE_SOME = '__some__';
Expand All @@ -48,40 +45,4 @@ public function evaluate(mixed $input): Result

return (new Result($valid, $input, $this, $template))->withChildren(...$children);
}

public function assert(mixed $input): void
{
try {
parent::assert($input);
} catch (NestedValidationException $exception) {
if (count($exception->getChildren()) === count($this->getRules()) && !$exception->hasCustomTemplate()) {
$exception->updateTemplate(self::TEMPLATE_NONE);
}

throw $exception;
}
}

public function check(mixed $input): void
{
foreach ($this->getRules() as $rule) {
$rule->check($input);
}
}

public function validate(mixed $input): bool
{
foreach ($this->getRules() as $rule) {
if (!$rule->validate($input)) {
return false;
}
}

return true;
}

protected function getStandardTemplate(mixed $input): string
{
return self::TEMPLATE_SOME;
}
}
50 changes: 1 addition & 49 deletions library/Rules/AnyOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,18 @@

namespace Respect\Validation\Rules;

use Respect\Validation\Attributes\ExceptionClass;
use Respect\Validation\Exceptions\NestedValidationException;
use Respect\Validation\Exceptions\ValidationException;
use Respect\Validation\Message\Template;
use Respect\Validation\Result;
use Respect\Validation\Rule;

use function array_map;
use function array_reduce;
use function count;

#[ExceptionClass(NestedValidationException::class)]
#[Template(
'At least one of these rules must pass for {{name}}',
'At least one of these rules must not pass for {{name}}',
)]
final class AnyOf extends AbstractComposite
final class AnyOf extends Composite
{
public function evaluate(mixed $input): Result
{
Expand All @@ -34,47 +29,4 @@ public function evaluate(mixed $input): Result

return (new Result($valid, $input, $this))->withChildren(...$children);
}

public function assert(mixed $input): void
{
try {
parent::assert($input);
} catch (NestedValidationException $exception) {
if (count($exception->getChildren()) === count($this->getRules())) {
throw $exception;
}
}
}

public function validate(mixed $input): bool
{
foreach ($this->getRules() as $v) {
if ($v->validate($input)) {
return true;
}
}

return false;
}

public function check(mixed $input): void
{
foreach ($this->getRules() as $v) {
try {
$v->check($input);

return;
} catch (ValidationException $e) {
if (!isset($firstException)) {
$firstException = $e;
}
}
}

if (isset($firstException)) {
throw $firstException;
}

throw $this->reportError($input);
}
}
68 changes: 68 additions & 0 deletions library/Rules/Composite.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

/*
* Copyright (c) Alexandre Gomes Gaigalas <[email protected]>
* SPDX-License-Identifier: MIT
*/

declare(strict_types=1);

namespace Respect\Validation\Rules;

use Respect\Validation\Helpers\DeprecatedValidatableMethods;
use Respect\Validation\Validatable;

abstract class Composite implements Validatable
{
use DeprecatedValidatableMethods;

/** @var array<Validatable> */
private readonly array $rules;

private ?string $name = null;

private ?string $template = null;

public function __construct(Validatable ...$rules)
{
$this->rules = $rules;
}

/** @return array<Validatable> */
public function getRules(): array
{
return $this->rules;
}

public function setName(string $name): static
{
foreach ($this->getRules() as $rule) {
if ($rule->getName() && $this->name !== $rule->getName()) {
continue;
}

$rule->setName($name);
}

$this->name = $name;

return $this;
}

public function getName(): ?string
{
return $this->name;
}

public function setTemplate(string $template): static
{
$this->template = $template;

return $this;
}

public function getTemplate(): ?string
{
return $this->template;
}
}
28 changes: 1 addition & 27 deletions library/Rules/NoneOf.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,18 @@

namespace Respect\Validation\Rules;

use Respect\Validation\Attributes\ExceptionClass;
use Respect\Validation\Exceptions\NestedValidationException;
use Respect\Validation\Message\Template;
use Respect\Validation\Result;
use Respect\Validation\Rule;

use function array_map;
use function array_reduce;
use function count;

#[ExceptionClass(NestedValidationException::class)]
#[Template(
'None of these rules must pass for {{name}}',
'All of these rules must pass for {{name}}',
)]
final class NoneOf extends AbstractComposite
final class NoneOf extends Composite
{
public function evaluate(mixed $input): Result
{
Expand All @@ -33,26 +29,4 @@ public function evaluate(mixed $input): Result

return (new Result($valid, $input, $this))->withChildren(...$children);
}

public function assert(mixed $input): void
{
try {
parent::assert($input);
} catch (NestedValidationException $exception) {
if (count($exception->getChildren()) !== count($this->getRules())) {
throw $exception;
}
}
}

public function validate(mixed $input): bool
{
foreach ($this->getRules() as $rule) {
if ($rule->validate($input)) {
return false;
}
}

return true;
}
}
Loading

0 comments on commit f1b6f0c

Please sign in to comment.