Passed
Push — develop ( 514978...ea7cba )
by Daniel
05:33
created

ApiNormalizer::denormalize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 4
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Silverback\ApiComponentBundle\Serializer;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
7
use Silverback\ApiComponentBundle\Entity\Content\Component\Form\Form;
8
use Silverback\ApiComponentBundle\Entity\Content\FileInterface;
9
use Silverback\ApiComponentBundle\Entity\Content\Page;
10
use Silverback\ApiComponentBundle\Entity\Layout\Layout;
11
use Silverback\ApiComponentBundle\Factory\Entity\Content\Component\Form\FormViewFactory;
12
use Silverback\ApiComponentBundle\Imagine\PathResolver;
13
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
14
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
15
use Symfony\Component\Serializer\SerializerAwareInterface;
16
use Symfony\Component\Serializer\SerializerInterface;
17
18
final class ApiNormalizer implements NormalizerInterface, DenormalizerInterface, SerializerAwareInterface
19
{
20
    private $decorated;
21
    private $imagineCacheManager;
22
    private $formViewFactory;
23
    private $pathResolver;
24
    private $em;
25
26
    /**
27
     * FileNormalizer constructor.
28
     * @param NormalizerInterface $decorated
29
     * @param CacheManager $imagineCacheManager
30
     * @param FormViewFactory $formViewFactory
31
     * @param PathResolver $pathResolver
32
     * @param EntityManagerInterface $entityManager
33
     */
34 10
    public function __construct(
35
        NormalizerInterface $decorated,
36
        CacheManager $imagineCacheManager,
37
        FormViewFactory $formViewFactory,
38
        PathResolver $pathResolver,
39
        EntityManagerInterface $entityManager
40
    ) {
41 10
        if (!$decorated instanceof DenormalizerInterface) {
42
            throw new \InvalidArgumentException(sprintf('The decorated normalizer must implement the %s.', DenormalizerInterface::class));
43
        }
44 10
        $this->decorated = $decorated;
45 10
        $this->imagineCacheManager = $imagineCacheManager;
46 10
        $this->formViewFactory = $formViewFactory;
47 10
        $this->pathResolver = $pathResolver;
48 10
        $this->em = $entityManager;
49 10
    }
50
51
    /**
52
     * @param mixed $data
53
     * @param string|null $format
54
     * @return bool
55
     */
56 3
    public function supportsNormalization($data, $format = null): bool
57
    {
58 3
        return $this->decorated->supportsNormalization($data, $format);
59
    }
60
61
    /**
62
     * @param $object
63
     * @param string|null $format
64
     * @param array $context
65
     * @return array|bool|float|int|string
66
     * @throws \Symfony\Component\Serializer\Exception\LogicException
67
     * @throws \Symfony\Component\Serializer\Exception\InvalidArgumentException
68
     * @throws \Symfony\Component\Serializer\Exception\CircularReferenceException
69
     */
70 4
    public function normalize($object, $format = null, array $context = [])
71
    {
72 4
        $data = $this->decorated->normalize($object, $format, $context);
73
74 4
        if ($object instanceof FileInterface) {
75 1
            $data = array_merge($data, $this->getFileData($object));
76
        }
77 4
        if ($object instanceof Form) {
78 3
            $data['form'] = $this->formViewFactory->create($object);
79
        }
80 4
        if ($object instanceof Page) {
81
            if (!$object->getLayout()) {
82
                $object->setLayout($this->em->getRepository(Layout::class)->findOneBy(['default' => true]));
83
            }
84
        }
85
86 4
        return $data;
87
    }
88
89
    /**
90
     * @param \Silverback\ApiComponentBundle\Entity\Content\FileInterface $object
91
     * @return array
92
     */
93 1
    private function getFileData(FileInterface $object): array
94
    {
95 1
        $data = [];
96 1
        $filePath = $object->getFilePath();
97 1
        if ($filePath) {
98 1
            if (false !== \exif_imagetype($filePath)) {
99 1
                [$width, $height] = getimagesize($filePath);
100
            } else {
101
                $width = $height = 0;
102
            }
103 1
            $data['width'] = $width;
104 1
            $data['height'] = $height;
105
106 1
            $supported = $this->isImagineSupportedFile($filePath);
107 1
            foreach ($object::getImagineFilters() as $returnKey => $filter) {
108 1
                $data[$returnKey] = $supported ? parse_url(
109 1
                    $this->imagineCacheManager->getBrowserPath($this->pathResolver->resolve($filePath), $filter),
110 1
                    PHP_URL_PATH
111 1
                ) : null;
112
            }
113
        }
114 1
        return $data;
115
    }
116
117
    /**
118
     * @param mixed $data
119
     * @param string $type
120
     * @param string|null $format
121
     * @return bool
122
     */
123 3
    public function supportsDenormalization($data, $type, $format = null): bool
124
    {
125 3
        return $this->decorated->supportsDenormalization($data, $type, $format);
126
    }
127
128
    /**
129
     * @param mixed $data
130
     * @param string $class
131
     * @param string|null $format
132
     * @param array $context
133
     * @return object
134
     * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException
135
     * @throws \Symfony\Component\Serializer\Exception\RuntimeException
136
     * @throws \Symfony\Component\Serializer\Exception\LogicException
137
     * @throws \Symfony\Component\Serializer\Exception\InvalidArgumentException
138
     * @throws \Symfony\Component\Serializer\Exception\ExtraAttributesException
139
     * @throws \Symfony\Component\Serializer\Exception\BadMethodCallException
140
     * @throws \InvalidArgumentException
141
     */
142 1
    public function denormalize($data, $class, $format = null, array $context = [])
143
    {
144 1
        $context['allow_extra_attributes'] = $class === Form::class;
145 1
        return $this->decorated->denormalize($data, $class, $format, $context);
146
    }
147
148
    /**
149
     * @param SerializerInterface $serializer
150
     */
151 5
    public function setSerializer(SerializerInterface $serializer)
152
    {
153 5
        if ($this->decorated instanceof SerializerAwareInterface) {
154 5
            $this->decorated->setSerializer($serializer);
155
        }
156 5
    }
157
158
    /**
159
     * @param string $filePath
160
     * @return bool
161
     */
162 3
    public function isImagineSupportedFile(?string $filePath): bool
163
    {
164 3
        if (!$filePath) {
165
            return false;
166
        }
167
        try {
168 3
            $imageType = \exif_imagetype($filePath);
169 2
        } catch (\Exception $e) {
170 2
            return false;
171
        }
172 3
        return \in_array($imageType, [IMAGETYPE_JPEG, IMAGETYPE_JPEG2000, IMAGETYPE_PNG, IMAGETYPE_GIF], true);
173
    }
174
}
175