Passed
Push — develop ( 6438b7...305164 )
by Daniel
04:47
created

ApiNormalizer::getFileData()   C

Complexity

Conditions 8
Paths 3

Size

Total Lines 29
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 8.0069

Importance

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