BadRequestException::setErrors()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 10
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 18
ccs 10
cts 10
cp 1
crap 5
rs 9.6111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Inspirum\Balikobot\Exception;
6
7
use Inspirum\Balikobot\Definitions\Response;
8
use Throwable;
9
use function is_array;
10
use function is_numeric;
11
12
final class BadRequestException extends BaseException
13
{
14
    /**
15
     * BadRequestException constructor
16
     *
17
     * @param array<mixed> $response
18
     */
19 339
    public function __construct(
20
        array $response,
21
        int $statusCode = 400,
22
        ?Throwable $previous = null,
23
        ?string $message = null,
24
    ) {
25 339
        $this->setErrors($response);
26
27 339
        parent::__construct($response, $statusCode, $previous, $message);
28
    }
29
30
    /**
31
     * Set errors from response
32
     *
33
     * @param array<mixed> $response
34
     */
35 339
    private function setErrors(array $response): void
36
    {
37 339
        $i = 0;
38
39 339
        $packages = $this->resolveErrorsData($response);
40
41
        // add errors from all packages
42 339
        while (isset($packages[$i])) {
43 31
            if (is_array($packages[$i])) {
44 31
                $this->setErrorsForPackage($i, $packages[$i]);
45 2
            } elseif (is_numeric($packages[$i]) && $packages[$i] >= 400) {
46 1
                $this->setError($i, 'status', $this->getErrorMessage('status', (int) $packages[$i]));
47
            } else {
48 1
                $this->setError($i, 'status', 'Nespecifikovaná chyba.');
49
            }
50
51
            // try next package
52 31
            $i++;
53
        }
54
    }
55
56
    /**
57
     * Resolve errors data array
58
     *
59
     * @param array<mixed> $response
60
     *
61
     * @return array<mixed>
62
     */
63 339
    private function resolveErrorsData(array $response): array
64
    {
65 339
        if (isset($response['packages'])) {
66 15
            return $response['packages'];
67
        }
68
69 324
        if (isset($response['errors'])) {
70 2
            return $response['errors'];
71
        }
72
73 322
        return $response;
74
    }
75
76
    /**
77
     * Set errors for package
78
     *
79
     * @param array<mixed> $response
80
     */
81 31
    private function setErrorsForPackage(int $number, array $response): void
82
    {
83
        // response does not have full errors
84 31
        if (isset($response['errors']) === false) {
85
            // try to resolve errors from codes
86 23
            $this->setErrorsFromResponseCodes($number, $response);
87
88 23
            return;
89
        }
90
91
        // set errors for given package
92 8
        foreach ($response['errors'] as $error) {
93 8
            $this->setError($number, $error['attribute'], $error['message']);
94
        }
95
    }
96
97
    /**
98
     * Set errors from codes
99
     *
100
     * @param array<string,int|string> $response
101
     */
102 23
    private function setErrorsFromResponseCodes(int $number, array $response): void
103
    {
104 23
        foreach ($response as $key => $code) {
105
            // skip non-numeric codes
106 23
            if (is_numeric($code) === false || $code < 400) {
107 19
                continue;
108
            }
109
110
            // set errors from given package from response codes
111 15
            $this->setError($number, $key, $this->getErrorMessage($key, (int) $code));
112
        }
113
    }
114
115
    /**
116
     * Get error message from variables
117
     */
118 15
    private function getErrorMessage(string $key, int $code): string
119
    {
120
        // get error message from code
121 15
        if ($key === 'status') {
122 11
            return Response::STATUS_CODE_ERRORS[$code] ?? Response::STATUS_CODE_ERRORS[500];
123
        }
124
125 12
        if (isset(Response::PACKAGE_DATA_KEY_ERRORS[$code][$key])) {
126 5
            return Response::PACKAGE_DATA_KEY_ERRORS[$code][$key];
127
        }
128
129 10
        return Response::PACKAGE_DATA_ERRORS[$code] ?? 'Nespecifikovaná chyba.';
130
    }
131
132
    /**
133
     * Set new error message
134
     */
135 23
    private function setError(int $number, string $key, string $error): void
136
    {
137 23
        $this->errors[$number][$key] = $error;
138
    }
139
}
140