Completed
Pull Request — master (#8)
by Tomáš
02:25
created

BadRequestException::setErrorsForPackage()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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