Passed
Pull Request — master (#52)
by Daniel
06:04 queued 33s
created

UploadableNormalizer   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 15
eloc 33
c 1
b 0
f 0
dl 0
loc 80
ccs 0
cts 33
cp 0
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A hasCacheableSupportsMethod() 0 3 1
A __construct() 0 3 1
A supportsDenormalization() 0 3 2
A normalize() 0 8 1
A supportsNormalization() 0 6 4
A denormalize() 0 32 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 Ramsey\Uuid\Uuid;
17
use Silverback\ApiComponentBundle\AnnotationReader\UploadableAnnotationReader;
18
use Silverback\ApiComponentBundle\Model\Uploadable\Base64EncodedFile;
19
use Silverback\ApiComponentBundle\Model\Uploadable\UploadedBase64EncodedFile;
20
use Symfony\Component\HttpFoundation\File\Exception\FileException;
21
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
22
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
23
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
24
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
25
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
26
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
27
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
28
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
29
30
/**
31
 * @author Vincent Chalamon <[email protected]>
32
 */
33
final class UploadableNormalizer implements CacheableSupportsMethodInterface, ContextAwareDenormalizerInterface, DenormalizerAwareInterface, ContextAwareNormalizerInterface, NormalizerAwareInterface
34
{
35
    use DenormalizerAwareTrait;
36
    use NormalizerAwareTrait;
37
38
    private const ALREADY_CALLED = 'UPLOADABLE_NORMALIZER_ALREADY_CALLED';
39
40
    private UploadableAnnotationReader $annotationReader;
41
42
    public function __construct(UploadableAnnotationReader $annotationReader)
43
    {
44
        $this->annotationReader = $annotationReader;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50
    public function supportsDenormalization($data, $type, $format = null, array $context = []): bool
51
    {
52
        return !isset($context[self::ALREADY_CALLED]) && $this->annotationReader->isConfigured($type);
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58
    public function denormalize($data, $type, $format = null, array $context = [])
59
    {
60
        $context[self::ALREADY_CALLED] = true;
61
62
        foreach ($data as $fieldName => $value) {
63
            try {
64
                $reflectionProperty = new \ReflectionProperty($type, $fieldName);
65
            } catch (\ReflectionException $exception) {
66
                // Property does not exist on class: just ignore it.
67
                continue;
68
            }
69
70
            // Property is not an UploadableField: just ignore it.
71
            if (!$this->annotationReader->isFieldConfigured($reflectionProperty)) {
72
                continue;
73
            }
74
75
            // Value is empty: set it to null.
76
            if (empty($value)) {
77
                $data[$fieldName] = null;
78
                continue;
79
            }
80
81
            try {
82
                $file = new Base64EncodedFile($value);
83
                $data[$fieldName] = new UploadedBase64EncodedFile($file, Uuid::uuid4() . '.' . $file->getExtension());
84
            } catch (FileException $exception) {
85
                throw new NotNormalizableValueException($exception->getMessage());
86
            }
87
        }
88
89
        return $this->denormalizer->denormalize($data, $type, $format, $context);
90
    }
91
92
    public function supportsNormalization($data, $format = null, array $context = []): bool
93
    {
94
        return !isset($context[self::ALREADY_CALLED]) &&
95
            \is_object($data) &&
96
            !$data instanceof \Traversable &&
97
            $this->annotationReader->isConfigured($data);
98
    }
99
100
    public function normalize($object, $format = null, array $context = [])
101
    {
102
        $context[self::ALREADY_CALLED] = true;
103
104
        $mediaObjects = [];
105
        $context[MetadataNormalizer::METADATA_CONTEXT]['media_objects'] = $mediaObjects;
106
107
        return $this->normalizer->normalize($object, $format, $context);
108
    }
109
110
    public function hasCacheableSupportsMethod(): bool
111
    {
112
        return false;
113
    }
114
}
115