Passed
Push — main ( 59e738...1d09ac )
by Breno
01:57
created

ValidationException   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 22
c 2
b 0
f 0
dl 0
loc 72
rs 10
wmc 9

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getFactory() 0 3 1
A jsonSerialize() 0 3 1
A __construct() 0 4 1
A serializeViolations() 0 13 2
A toApiProblem() 0 7 1
A setFactory() 0 3 1
A hasFactory() 0 3 1
A getErrors() 0 3 1
1
<?php
2
declare(strict_types=1);
3
4
namespace BrenoRoosevelt\Validation\Exception;
5
6
use BrenoRoosevelt\Validation\Error;
7
use Exception;
8
use JsonSerializable;
9
use Phpro\ApiProblem\Http\HttpApiProblem;
10
use Throwable;
11
12
class ValidationException extends Exception implements ValidationExceptionInterface, JsonSerializable
13
{
14
    private static ?ValidationExceptionFactoryInterface $userDefinedFactory = null;
15
16
    /** @var Error[] */
17
    private array $errors;
18
19
    public function __construct(array $errors, ?string $message = "", int $code = 400, ?Throwable $previous = null)
20
    {
21
        $this->errors = array_filter($errors, fn($e) => $e instanceof Error);
22
        parent::__construct($message ?? '', $code, $previous);
23
    }
24
25
    /** @inheritDoc */
26
    public function getErrors(): array
27
    {
28
        return $this->errors;
29
    }
30
31
    public static function setFactory(?ValidationExceptionFactoryInterface $factory): void
32
    {
33
        self::$userDefinedFactory = $factory;
34
    }
35
36
    public static function hasFactory(): bool
37
    {
38
        return self::$userDefinedFactory instanceof ValidationExceptionFactoryInterface;
39
    }
40
41
    public static function getFactory(): ?ValidationExceptionFactoryInterface
42
    {
43
        return self::$userDefinedFactory;
44
    }
45
46
    /**
47
     * Convert to HttpApiProblem
48
     *
49
     * @return HttpApiProblem
50
     */
51
    public function toApiProblem(): HttpApiProblem
52
    {
53
        return new HttpApiProblem($this->getCode(), [
54
            'type' => HttpApiProblem::TYPE_HTTP_RFC,
55
            'title' => HttpApiProblem::getTitleForStatusCode($this->getCode()),
56
            'detail' => $this->message ?? 'Input validation failed',
57
            'violations' => $this->serializeViolations(),
58
        ]);
59
    }
60
61
    private function serializeViolations(): array
62
    {
63
        $violations = [];
64
        foreach ($this->errors as $violation) {
65
            $violationEntry = [
66
                'propertyPath' => $violation->field(),
67
                'title' => $violation->message(),
68
            ];
69
70
            $violations[] = $violationEntry;
71
        }
72
73
        return $violations;
74
    }
75
76
    /**
77
     * Provides an RFC 7807 compliant response
78
     *
79
     * @return array
80
     */
81
    public function jsonSerialize(): array
82
    {
83
        return $this->toApiProblem()->toArray();
84
    }
85
}
86