Completed
Pull Request — master (#8)
by Tomáš
03:09
created

BadRequestException::setError()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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