Issues (31)

src/Adapter/SerializerAdapter.php (3 issues)

1
<?php
2
/**
3
 * Copyright (c) 2020.
4
 * @author PaweÅ‚ Antosiak <[email protected]>
5
 */
6
7
declare(strict_types=1);
8
9
namespace Gorynych\Adapter;
10
11
use Gorynych\Exception\NotDeserializableException;
12
use Symfony\Component\Config\FileLocatorInterface;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\Serializer\Encoder\EncoderInterface;
15
use Symfony\Component\Serializer\Encoder\JsonEncoder;
16
use Symfony\Component\Serializer\Encoder\XmlEncoder;
17
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
18
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
19
use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader;
20
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
21
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
22
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
23
use Symfony\Component\Serializer\Serializer;
24
use Symfony\Component\Serializer\SerializerInterface;
25
26
class SerializerAdapter
27
{
28
    /** @var SerializerInterface|NormalizerInterface */
29
    protected $serializer;
30
    protected FileLocatorInterface $configLocator;
31
32
    public function __construct(FileLocatorInterface $configLocator)
33
    {
34
        $this->configLocator = $configLocator;
35
    }
36
37
    /**
38
     * Normalizes provided data
39
     *
40
     * @param object|object[] $data
41
     * @param mixed[] $context
42
     * @return mixed[]
43
     */
44
    public function normalize($data, array $context = []): array
45
    {
46
        return $this->serializer->normalize($data, null, $context);
47
    }
48
49
    /**
50
     * Deserializes input data into specified object
51
     *
52
     * @param string $data
53
     * @param string $outputClass
54
     * @param string $format
55
     * @param mixed[] $context
56
     * @return object
57
     *
58
     * @throws NotDeserializableException
59
     */
60 1
    public function deserialize(string $data, string $outputClass, string $format, array $context = []): object
61
    {
62
        try {
63 1
            return $this->serializer->deserialize($data, $outputClass, $format, $context);
0 ignored issues
show
The method deserialize() does not exist on Symfony\Component\Serial...zer\NormalizerInterface. It seems like you code against a sub-type of Symfony\Component\Serial...zer\NormalizerInterface such as Symfony\Component\Serializer\Serializer. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

63
            return $this->serializer->/** @scrutinizer ignore-call */ deserialize($data, $outputClass, $format, $context);
Loading history...
Bug Best Practice introduced by
The expression return $this->serializer...ass, $format, $context) could return the type array which is incompatible with the type-hinted return object. Consider adding an additional type-check to rule them out.
Loading history...
64 1
        } catch (NotEncodableValueException $e) {
65 1
            throw new NotDeserializableException($e->getMessage());
66
        }
67
    }
68
69
    /**
70
     * Returns TRUE is normalization for provided data representation can be processed
71
     *
72
     * @param mixed $data
73
     */
74 4
    public function canNormalize($data): bool
75
    {
76
        return (
77 4
            is_object($data) ||
78 4
            (is_array($data) && !empty($data) && is_object(current($data)))
79
        );
80
    }
81
82
    /**
83
     * Returns TRUE if deserialization for provided type can be processed
84
     */
85 3
    public function canDeserialize(string $type): bool
86
    {
87 3
        return Request::class !== $type && class_exists($type);
88
    }
89
90
    /**
91
     * Setups serializer
92
     *
93
     * @param string|null $definition Serializer definition name
94
     * @return self
95
     */
96
    public function setup(string $definition = null): self
97
    {
98
        if (false === empty($definition)) {
99
            $classMetadataFactory = new ClassMetadataFactory(new YamlFileLoader(
100
                $this->configLocator->locate("serializer/{$definition}.yaml")
0 ignored issues
show
It seems like $this->configLocator->lo.../'.$definition.'.yaml') can also be of type array; however, parameter $file of Symfony\Component\Serial...leLoader::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

100
                /** @scrutinizer ignore-type */ $this->configLocator->locate("serializer/{$definition}.yaml")
Loading history...
101
            ));
102
        }
103
104
        $this->serializer = new Serializer(
105
            [new DateTimeNormalizer(), new ObjectNormalizer($classMetadataFactory ?? null)],
106
            $this->getEncoders()
107
        );
108
109
        return $this;
110
    }
111
112
    /**
113
     * @return EncoderInterface[]
114
     */
115
    protected function getEncoders(): array
116
    {
117
        return [new JsonEncoder(), new XmlEncoder()];
118
    }
119
}
120