Completed
Push — master ( bba0b9...7bef16 )
by Vitaliy
01:47
created

ObjectNormalizer   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 96
Duplicated Lines 12.5 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 1
dl 12
loc 96
ccs 30
cts 30
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A removeNullableAttributes() 0 6 1
D normalize() 12 46 10

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
declare(strict_types = 1);
4
5
/*
6
 * This file is part of the FiveLab Resource package
7
 *
8
 * (c) FiveLab
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code
12
 */
13
14
namespace FiveLab\Component\Resource\Serializer\Normalizer;
15
16
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
17
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
18
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
19
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
20
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer as SymfonyObjectNormalizer;
21
22
/**
23
 * Extend default object normalizer for add ability for run custom code before and after normalization
24
 * and all ability for remove nullable attributes from structure.
25
 *
26
 * We should extend default symfony serializer for add ability for adding custom normalizers.
27
 */
28
class ObjectNormalizer extends SymfonyObjectNormalizer
29
{
30
    /**
31
     * @var bool
32
     */
33
    private $serializeNull;
34
35
    /**
36
     * Constructor.
37
     *
38
     * @param ClassMetadataFactoryInterface  $classMetadataFactory
39
     * @param NameConverterInterface         $nameConverter
40
     * @param PropertyAccessorInterface      $propertyAccessor
41
     * @param PropertyTypeExtractorInterface $propertyTypeExtractor
42
     * @param bool                           $serializeNull
43
     */
44 11
    public function __construct(
45
        ClassMetadataFactoryInterface $classMetadataFactory = null,
46
        NameConverterInterface $nameConverter = null,
47
        PropertyAccessorInterface $propertyAccessor = null,
48
        PropertyTypeExtractorInterface $propertyTypeExtractor = null,
49
        bool $serializeNull = true
50
    ) {
51 11
        parent::__construct($classMetadataFactory, $nameConverter, $propertyAccessor, $propertyTypeExtractor);
52
53 11
        $this->serializeNull = $serializeNull;
54 11
    }
55
56
57
    /**
58
     * {@inheritdoc}
59
     *
60
     * @throws \InvalidArgumentException
61
     * @throws \LogicException
62
     */
63 9
    public function normalize($object, $format = null, array $context = []): array
64
    {
65
        // Call to before normalization callback
66 9
        if (array_key_exists('before_normalization', $context)) {
67 2
            $beforeNormalization = $context['before_normalization'];
68
69 2 View Code Duplication
            if (!is_callable($beforeNormalization)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70 1
                throw new \InvalidArgumentException(sprintf(
71 1
                    'Invalid callable for before normalization. "%s" given.',
72 1
                    is_object($beforeNormalization) ? get_class($beforeNormalization) : gettype($beforeNormalization)
73
                ));
74
            }
75
76 1
            $beforeNormalization($object, $format, $context);
77
        }
78
79
        // Normalize object
80 8
        $data = parent::normalize($object, $format, $context);
81
82 8
        if (!$this->serializeNull) {
83 1
            $data = $this->removeNullableAttributes($data);
84
        }
85
86
        // Call to after normalization callback
87 8
        if (array_key_exists('after_normalization', $context)) {
88 3
            $afterNormalization = $context['after_normalization'];
89
90 3 View Code Duplication
            if (!is_callable($afterNormalization)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91 1
                throw new \InvalidArgumentException(sprintf(
92 1
                    'Invalid callable for after normalization. "%s" given.',
93 1
                    is_object($afterNormalization) ? get_class($afterNormalization) : gettype($afterNormalization)
94
                ));
95
            }
96
97 2
            $data = $afterNormalization($data, $object, $format, $context);
98
99 2
            if (!is_array($data)) {
100 1
                throw new \LogicException(sprintf(
101 1
                    'The after normalization callback should return array, but "%s" given.',
102 1
                    is_object($data) ? get_class($data) : gettype($data)
103
                ));
104
            }
105
        }
106
107 6
        return $data;
108
    }
109
110
    /**
111
     * Remove nullable attributes
112
     *
113
     * @param array $data
114
     *
115
     * @return array
116
     */
117
    private function removeNullableAttributes(array $data): array
118
    {
119 1
        return array_filter($data, function ($value) {
120 1
            return (bool) $value;
121 1
        });
122
    }
123
}
124