convertExceptionToApieResponse()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 29
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 4
eloc 20
c 2
b 0
f 1
nc 8
nop 2
dl 0
loc 29
rs 9.6
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\HttpKernel\Exception\NotAcceptableHttpException;
13
use W2w\Lib\Apie\Core\Models\ApiResourceFacadeResponse;
14
use W2w\Lib\Apie\Exceptions\ValidationException as ApieValidationException;
15
use W2w\Lib\Apie\Interfaces\ResourceSerializerInterface;
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());
0 ignored issues
show
Deprecated Code introduced by
The class W2w\Lib\Apie\Exceptions\ValidationException has been deprecated: use \W2w\Lib\ApieObjectAccessNormalizer\Exceptions\ValidationException ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

39
            $exception = /** @scrutinizer ignore-deprecated */ new ApieValidationException($exception->errors());
Loading history...
40
        }
41
        $apiRes = new ApiResourceFacadeResponse(
42
            app(ResourceSerializerInterface::class),
43
            $exception,
44
            $request->header('accept')
45
        );
46
        try {
47
            $response = $apiRes->getResponse();
48
        } catch (NotAcceptableHttpException $notAcceptableHttpException) {
49
            // accept header is not allowed, so assume to return default accept header.
50
            $apiRes = new ApiResourceFacadeResponse(
51
                app(ResourceSerializerInterface::class),
52
                $exception,
53
                null
54
            );
55
            $response = $apiRes->getResponse();
56
        }
57
        return $this->httpFoundationFactory->createResponse($response->withStatus($statusCode));
58
    }
59
60
    public function isApieAction(Request $request): bool
61
    {
62
        $route = $request->route();
63
        if (!$route) {
64
            return false;
65
        }
66
        // needed for Lumen
67
        if (is_array($route)) {
0 ignored issues
show
introduced by
The condition is_array($route) is always false.
Loading history...
68
            $name = $route['1']['as'] ?? '';
69
            return Str::startsWith($name, 'apie.');
70
        }
71
        return Str::startsWith($route->getName(), 'apie.');
72
    }
73
74
    private function getStatusCodeFromClassMapping(string $className): ?int
75
    {
76
        if (isset($this->exceptionMapping[$className])) {
77
            return (int) $this->exceptionMapping[$className];
78
        } else {
79
            foreach ($this->exceptionMapping as $mappedClassName => $intendedStatusCode) {
80
                if (is_a($className, $mappedClassName, true)) {
81
                    return (int) $intendedStatusCode;
82
                }
83
            }
84
        }
85
        return null;
86
    }
87
}
88