Passed
Push — develop ( 762085...4c0d99 )
by Daniel
05:38
created

ApiNormalizer::normalize()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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