Passed
Push — master ( 80001a...1201cf )
by
unknown
03:47
created

ApieExceptionToResponse::isApieAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 4
c 1
b 0
f 1
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
namespace W2w\Laravel\Apie\Services;
4
5
use Exception;
6
use Illuminate\Http\Request;
7
use Illuminate\Support\Str;
8
use Illuminate\Validation\ValidationException;
9
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\HttpKernel\Exception\HttpException;
12
use Symfony\Component\Serializer\Serializer;
13
use W2w\Lib\Apie\Encodings\FormatRetriever;
14
use W2w\Lib\Apie\Exceptions\ValidationException as ApieValidationException;
15
use W2w\Lib\Apie\Models\ApiResourceFacadeResponse;
16
17
class ApieExceptionToResponse
18
{
19
    private $httpFoundationFactory;
20
21
    private $exceptionMapping;
22
23
    public function __construct(HttpFoundationFactory $httpFoundationFactory, array $exceptionMapping)
24
    {
25
        $this->httpFoundationFactory = $httpFoundationFactory;
26
        $this->exceptionMapping = $exceptionMapping;
27
    }
28
29
    public function convertExceptionToApieResponse(Request $request, Exception $exception): Response
30
    {
31
        $statusCode = 500;
32
        if ($exception instanceof HttpException) {
33
            $statusCode = $exception->getStatusCode();
34
        }
35
        $statusCode = $this->getStatusCodeFromClassMapping(get_class($exception)) ?? $statusCode;
36
37
        if ($exception instanceof ValidationException) {
38
            $statusCode = 422;
39
            $exception = new ApieValidationException($exception->errors());
40
        }
41
        $apiRes = new ApiResourceFacadeResponse(
42
            resolve(Serializer::class),
43
            [],
44
            $exception,
45
            resolve(FormatRetriever::class),
46
            $request->header('accept')
47
        );
48
        return $this->httpFoundationFactory->createResponse($apiRes->getResponse()->withStatus($statusCode));
49
    }
50
51
    public function isApieAction(Request $request): bool
52
    {
53
        $route = $request->route();
54
        if (!$route) {
55
            return false;
56
        }
57
        return Str::startsWith($route->getName(), 'apie.');
58
    }
59
60
    private function getStatusCodeFromClassMapping(string $className): ?int
61
    {
62
        if (isset($this->exceptionMapping[$className])) {
63
            return (int) $this->exceptionMapping[$className];
64
        } else {
65
            foreach ($this->exceptionMapping as $mappedClassName => $intendedStatusCode) {
66
                if (is_a($className, $mappedClassName, true)) {
67
                    return (int) $intendedStatusCode;
68
                }
69
            }
70
        }
71
        return null;
72
    }
73
}
74