Passed
Pull Request — master (#52)
by Vincent
11:12 queued 04:00
created

UploadableNormalizer::supportsDenormalization()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 2
nc 2
nop 4
crap 6
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Component Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentBundle\Serializer\Normalizer;
15
16
use Hshn\Base64EncodedFile\HttpFoundation\File\Base64EncodedFile;
17
use Silverback\ApiComponentBundle\Helper\UploadableHelper;
18
use Symfony\Component\HttpFoundation\File\Exception\FileException;
19
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
20
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
21
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
22
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
23
24
/**
25
 * @author Vincent Chalamon <[email protected]>
26
 */
27
final class UploadableNormalizer implements CacheableSupportsMethodInterface, ContextAwareDenormalizerInterface, DenormalizerAwareInterface
28
{
29
    use DenormalizerAwareTrait;
30
31
    private const ALREADY_CALLED = 'UPLOADABLE_NORMALIZER_ALREADY_CALLED';
32
33
    private UploadableHelper $uploadableHelper;
34
35
    public function __construct(UploadableHelper $uploadableHelper)
36
    {
37
        $this->uploadableHelper = $uploadableHelper;
38
    }
39
40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function denormalize($data, $type, $format = null, array $context = [])
44
    {
45
        $context[self::ALREADY_CALLED] = true;
46
47
        foreach ($data as $fieldName => $value) {
48
            try {
49
                $reflectionProperty = new \ReflectionProperty($type, $fieldName);
50
            } catch (\ReflectionException $exception) {
51
                // Property does not exist on class: just ignore it.
52
                continue;
53
            }
54
55
            // Property is not an UploadableField: just ignore it.
56
            if (!$this->uploadableHelper->isFieldConfigured($reflectionProperty)) {
57
                continue;
58
            }
59
60
            // Value is empty: set it to null.
61
            if (empty($value)) {
62
                $data[$fieldName] = null;
63
                continue;
64
            }
65
66
            // Convert base64 string to UploadableFile.
67
            try {
68
                $data[$fieldName] = new Base64EncodedFile($value);
69
            } catch (FileException $exception) {
70
                // Invalid base64.
71
                // todo Should throw a violation error?
72
            }
73
        }
74
75
        return $this->denormalizer->denormalize($data, $type, $format, $context);
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     */
81
    public function supportsDenormalization($data, $type, $format = null, array $context = []): bool
82
    {
83
        return !isset($context[self::ALREADY_CALLED]) && $this->uploadableHelper->isConfigured($type);
84
    }
85
86
    public function hasCacheableSupportsMethod(): bool
87
    {
88
        return false;
89
    }
90
}
91