Completed
Push — main ( 5cdab0...0c282f )
by Niels
21s queued 17s
created

AbstractProblemExceptionNormalizer   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 29
c 1
b 0
f 1
dl 0
loc 77
rs 10
wmc 15

6 Methods

Rating   Name   Duplication   Size   Complexity  
A supportsNormalization() 0 7 2
A removeDetailsToPreventInformationDisclosure() 0 11 4
A getSupportedTypes() 0 4 1
A doNormalize() 0 17 3
A __construct() 0 3 1
A unsetKeysWithNullValue() 0 13 4
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the OpenapiBundle package.
7
 *
8
 * (c) Niels Nijens <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Nijens\OpenapiBundle\ExceptionHandling\Normalizer;
15
16
use Nijens\OpenapiBundle\ExceptionHandling\Exception\ProblemExceptionInterface;
17
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
18
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
19
use Symfony\Component\Serializer\Exception\LogicException;
20
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
21
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
22
use Throwable;
23
24
/**
25
 * Normalizes a {@see Throwable} implementing the {@see ProblemExceptionInterface}.
26
 *
27
 * @author Niels Nijens <[email protected]>
28
 */
29
abstract class AbstractProblemExceptionNormalizer implements NormalizerInterface, NormalizerAwareInterface
30
{
31
    use NormalizerAwareTrait;
32
33
    private const ALREADY_CALLED = 'nijens_openapi.problem_exception_normalizer.already_called';
34
35
    /**
36
     * @var bool
37
     */
38
    private $debug;
39
40
    public function __construct(bool $debug = false)
41
    {
42
        $this->debug = $debug;
43
    }
44
45
    protected function doNormalize($object, $format = null, array $context = []): array
46
    {
47
        if ($object instanceof ProblemExceptionInterface === false) {
48
            throw new InvalidArgumentException(sprintf('The object must implement "%s".', ProblemExceptionInterface::class));
49
        }
50
51
        if (isset($context[self::ALREADY_CALLED])) {
52
            throw new LogicException(sprintf('The normalizer "%s" can only be called once.', get_class($this)));
53
        }
54
55
        $context[self::ALREADY_CALLED] = true;
56
57
        $data = $this->normalizer->normalize($object, $format, $context);
58
59
        $this->removeDetailsToPreventInformationDisclosure($object, $data);
60
61
        return $this->unsetKeysWithNullValue($data);
62
    }
63
64
    public function supportsNormalization($data, $format = null, array $context = []): bool
65
    {
66
        if (isset($context[self::ALREADY_CALLED])) {
67
            return false;
68
        }
69
70
        return $data instanceof ProblemExceptionInterface;
71
    }
72
73
    public function getSupportedTypes(?string $format): array
0 ignored issues
show
Unused Code introduced by
The parameter $format is not used and could be removed. ( Ignorable by Annotation )

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

73
    public function getSupportedTypes(/** @scrutinizer ignore-unused */ ?string $format): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
74
    {
75
        return [
76
            ProblemExceptionInterface::class => false,
77
        ];
78
    }
79
80
    private function removeDetailsToPreventInformationDisclosure(ProblemExceptionInterface $object, array &$data): void
81
    {
82
        if ($this->debug) {
83
            return;
84
        }
85
86
        if ($object->getPrevious() === null || $object->getPrevious() instanceof HttpExceptionInterface) {
87
            return;
88
        }
89
90
        unset($data['detail']);
91
    }
92
93
    private function unsetKeysWithNullValue(array $data): array
94
    {
95
        foreach ($data as $key => $value) {
96
            if (is_array($value)) {
97
                $data[$key] = $this->unsetKeysWithNullValue($value);
98
            }
99
100
            if ($value === null) {
101
                unset($data[$key]);
102
            }
103
        }
104
105
        return $data;
106
    }
107
}
108