Test Failed
Branch develop (ac2838)
by Daniel
09:09
created

ApiNormalizer::supportsDenormalization()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Silverback\ApiComponentBundle\Serializer;
4
5
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
6
use Silverback\ApiComponentBundle\Entity\Component\AbstractComponent;
7
use Silverback\ApiComponentBundle\Entity\Component\FileInterface;
8
use Silverback\ApiComponentBundle\Entity\Component\Form\Form;
9
use Silverback\ApiComponentBundle\Factory\FormFactory;
10
use Symfony\Component\Filesystem\Filesystem;
11
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
12
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
13
use Symfony\Component\Serializer\SerializerAwareInterface;
14
use Symfony\Component\Serializer\SerializerInterface;
15
16
final class ApiNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
17
{
18
    private $decorated;
19
    private $projectDir;
20
    private $imagineCacheManager;
21
    private $formFactory;
22
23
    /**
24
     * FileNormalizer constructor.
25
     * @param NormalizerInterface $decorated
26
     * @param string $projectDir
27
     * @param CacheManager $imagineCacheManager
28
     * @param FormFactory $formFactory
29
     * @throws \InvalidArgumentException
30
     */
31
    public function __construct(
32
        NormalizerInterface $decorated,
33
        string $projectDir,
34
        CacheManager $imagineCacheManager,
35
        FormFactory $formFactory
36
    ) {
37
        if (!$decorated instanceof DenormalizerInterface) {
38
            throw new \InvalidArgumentException(sprintf('The decorated normalizer must implement the %s.', DenormalizerInterface::class));
39
        }
40
41
        $this->decorated = $decorated;
42
        $this->projectDir = $projectDir;
43
        $this->imagineCacheManager = $imagineCacheManager;
44
        $this->formFactory = $formFactory;
45
    }
46
47
    /**
48
     * @param mixed $data
49
     * @param null $format
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $format is correct as it would always require null to be passed?
Loading history...
50
     * @return bool
51
     */
52
    public function supportsNormalization($data, $format = null): bool
53
    {
54
        return $this->decorated->supportsNormalization($data, $format);
55
    }
56
57
    /**
58
     * @param $object
59
     * @param null $format
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $format is correct as it would always require null to be passed?
Loading history...
60
     * @param array $context
61
     * @return array|bool|float|int|string
62
     * @throws \Symfony\Component\Serializer\Exception\LogicException
63
     * @throws \Symfony\Component\Serializer\Exception\InvalidArgumentException
64
     * @throws \Symfony\Component\Serializer\Exception\CircularReferenceException
65
     */
66
    public function normalize($object, $format = null, array $context = [])
67
    {
68
        $data = $this->decorated->normalize($object, $format, $context);
69
70
        if ($object instanceof FileInterface) {
71
            $data = array_merge($data, $this->getFileData($object));
72
        }
73
        if ($object instanceof Form) {
74
            $data['form'] = $this->formFactory->createFormView($object);
75
        }
76
77
        return $data;
78
    }
79
80
    /**
81
     * @param FileInterface $object
82
     * @return array
83
     */
84
    private function getFileData(FileInterface $object)
85
    {
86
        $data = [];
87
        $originalFilePath = $object->getFilePath();
88
        /* @var $object FileInterface */
89
        $filePath = $this->getRealFilePath($originalFilePath);
90
        if ($filePath) {
91
            if (false !== \exif_imagetype($filePath)) {
92
                [$width, $height] = getimagesize($filePath);
93
            } else {
94
                $width = $height = 0;
95
            }
96
            $data['width'] = $width;
97
            $data['height'] = $height;
98
99
            $supported = $this->isImagineSupportedFile($originalFilePath);
100
            foreach ($object::getImagineFilters() as $returnKey => $filter) {
101
                $data[$returnKey] = $supported ? parse_url(
102
                    $this->imagineCacheManager->getBrowserPath($originalFilePath, $filter),
103
                    PHP_URL_PATH
104
                ) : null;
105
            }
106
        }
107
        return $data;
108
    }
109
110
    /**
111
     * @param mixed $data
112
     * @param string $type
113
     * @param null $format
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $format is correct as it would always require null to be passed?
Loading history...
114
     * @return bool
115
     */
116
    public function supportsDenormalization($data, $type, $format = null): bool
117
    {
118
        return $this->decorated->supportsDenormalization($data, $type, $format);
119
    }
120
121
    /**
122
     * @param mixed $data
123
     * @param string $class
124
     * @param null $format
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $format is correct as it would always require null to be passed?
Loading history...
125
     * @param array $context
126
     * @return object
127
     * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException
128
     * @throws \Symfony\Component\Serializer\Exception\RuntimeException
129
     * @throws \Symfony\Component\Serializer\Exception\LogicException
130
     * @throws \Symfony\Component\Serializer\Exception\InvalidArgumentException
131
     * @throws \Symfony\Component\Serializer\Exception\ExtraAttributesException
132
     * @throws \Symfony\Component\Serializer\Exception\BadMethodCallException
133
     * @throws \InvalidArgumentException
134
     */
135
    public function denormalize($data, $class, $format = null, array $context = [])
136
    {
137
        $context['allow_extra_attributes'] = $class === Form::class;
138
        $entity = $this->decorated->denormalize($data, $class, $format, $context);
139
        if (
140
            $entity instanceof AbstractComponent &&
141
            $parentComponent = $entity->getParent()
142
        ) {
143
            $entity->addToParentComponent($parentComponent);
144
        }
145
        return $entity;
146
    }
147
148
    /**
149
     * @param SerializerInterface $serializer
150
     */
151
    public function setSerializer(SerializerInterface $serializer)
152
    {
153
        if ($this->decorated instanceof SerializerAwareInterface) {
154
            $this->decorated->setSerializer($serializer);
155
        }
156
    }
157
158
    /**
159
     * @param null|string $filePath
160
     * @return null|string
161
     */
162
    private function getRealFilePath(?string $filePath): ?string
163
    {
164
        if (!$filePath || trim($filePath) === '') {
165
            return null;
166
        }
167
        $fs = new Filesystem();
168
        $filePath = $this->projectDir . '/public/' . $filePath;
169
        return $fs->exists($filePath) ? $filePath : null;
170
    }
171
172
    /**
173
     * @param string $filePath
174
     * @return bool
175
     */
176
    public function isImagineSupportedFile(?string $filePath): bool
177
    {
178
        $filePath = $this->getRealFilePath($filePath);
179
        if (!$filePath) {
180
            return false;
181
        }
182
        $imageType = \exif_imagetype($filePath);
183
        if (false === $imageType) {
0 ignored issues
show
introduced by
The condition false === $imageType can never be true.
Loading history...
184
            return false;
185
        }
186
        return \in_array($imageType, [IMAGETYPE_JPEG, IMAGETYPE_JPEG2000, IMAGETYPE_PNG, IMAGETYPE_GIF], true);
187
    }
188
}
189