Serializer   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 7
dl 0
loc 118
ccs 60
cts 60
cp 1
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A serialize() 0 4 1
A deserialize() 0 4 1
A convertContext() 0 21 4
C createExclusionStrategies() 0 54 12
1
<?php
2
3
/*
4
 * This file is part of the Ivory Serializer bundle package.
5
 *
6
 * (c) Eric GELOEN <[email protected]>
7
 *
8
 * For the full copyright and license information, please read the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ivory\SerializerBundle\FOS;
13
14
use FOS\RestBundle\Context\Context as FOSContext;
15
use FOS\RestBundle\Serializer\Serializer as FOSSerializerInterface;
16
use Ivory\Serializer\Context\Context;
17
use Ivory\Serializer\Exclusion\ChainExclusionStrategy;
18
use Ivory\Serializer\Exclusion\ExclusionStrategyInterface;
19
use Ivory\Serializer\Exclusion\GroupsExclusionStrategy;
20
use Ivory\Serializer\Exclusion\MaxDepthExclusionStrategy;
21
use Ivory\Serializer\Exclusion\VersionExclusionStrategy;
22
use Ivory\Serializer\SerializerInterface;
23
24
/**
25
 * @author GeLo <[email protected]>
26
 */
27
class Serializer implements FOSSerializerInterface
28
{
29
    /**
30
     * @var SerializerInterface
31
     */
32
    private $serializer;
33
34
    /**
35
     * @param SerializerInterface $serializer
36
     */
37 90
    public function __construct(SerializerInterface $serializer)
38
    {
39 90
        $this->serializer = $serializer;
40 90
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45 81
    public function serialize($data, $format, FOSContext $context)
46
    {
47 81
        return $this->serializer->serialize($data, $format, $this->convertContext($context));
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 81
    public function deserialize($data, $type, $format, FOSContext $context)
54
    {
55 81
        return $this->serializer->deserialize($data, $type, $format, $this->convertContext($context));
56
    }
57
58
    /**
59
     * @param FOSContext $fosContext
60
     *
61
     * @return Context
62
     */
63 81
    private function convertContext(FOSContext $fosContext)
64
    {
65 81
        $context = new Context();
66 81
        $context->addOptions($fosContext->getAttributes());
67
68 81
        if ($fosContext->getSerializeNull() !== null) {
69 9
            $context->setIgnoreNull(!$fosContext->getSerializeNull());
70 7
        }
71
72 81
        $exclusionStrategies = $this->createExclusionStrategies($fosContext);
73
74 63
        if (!empty($exclusionStrategies)) {
75 45
            $exclusionStrategy = count($exclusionStrategies) > 1
76 37
                ? new ChainExclusionStrategy($exclusionStrategies)
77 45
                : array_shift($exclusionStrategies);
78
79 45
            $context->setExclusionStrategy($exclusionStrategy);
0 ignored issues
show
Bug introduced by
It seems like $exclusionStrategy defined by count($exclusionStrategi...t($exclusionStrategies) on line 75 can be null; however, Ivory\Serializer\Context...:setExclusionStrategy() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
80 35
        }
81
82 63
        return $context;
83
    }
84
85
    /**
86
     * @param FOSContext $context
87
     *
88
     * @return ExclusionStrategyInterface[]
89
     */
90 81
    private function createExclusionStrategies(FOSContext $context)
91
    {
92 81
        $exclusionStrategies = [];
93
94 81
        $groups = $context->getGroups();
95 81
        $version = $context->getVersion();
96
97 81
        if (!empty($groups)) {
98 9
            $exclusionStrategies[] = new GroupsExclusionStrategy($groups);
99 7
        }
100
101 81
        if (!empty($version)) {
102 9
            $exclusionStrategies[] = new VersionExclusionStrategy($version);
103 7
        }
104
105 81
        if (method_exists($context, 'isMaxDepthEnabled')) {
106 63
            if ($context->isMaxDepthEnabled()) {
107 23
                $exclusionStrategies[] = new MaxDepthExclusionStrategy();
108 5
            }
109 45
        } else {
110 18
            $maxDepth = $context->getMaxDepth();
0 ignored issues
show
Deprecated Code introduced by
The method FOS\RestBundle\Context\Context::getMaxDepth() has been deprecated with message: since version 2.1, to be removed in 3.0. Use {@link self::isMaxDepthEnabled()} instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
111
112 18
            if (!empty($maxDepth)) {
113 2
                $exclusionStrategies[] = new MaxDepthExclusionStrategy($maxDepth);
114 2
            }
115
        }
116
117 81
        $customExclusionStrategies = $context->getAttribute($attribute = 'ivory_exclusion_strategies') ?: [];
118
119 81
        if (!is_array($customExclusionStrategies) && !$customExclusionStrategies instanceof \Traversable) {
120 9
            throw new \RuntimeException(sprintf(
121 9
                'The "%s" context attribute must be an array or implement "%s".',
122 7
                $attribute,
123 2
                \Traversable::class
124 7
            ));
125
        }
126
127 72
        foreach ($customExclusionStrategies as $customExclusionStrategy) {
128 27
            if (!$customExclusionStrategy instanceof ExclusionStrategyInterface) {
129 9
                throw new \RuntimeException(sprintf(
130 9
                    'The "%s" context attribute must be an array of "%s", got "%s".',
131 7
                    $attribute,
132 9
                    ExclusionStrategyInterface::class,
133 9
                    is_object($customExclusionStrategy)
134 7
                        ? get_class($customExclusionStrategy)
135 9
                        : gettype($customExclusionStrategy)
136 7
                ));
137
            }
138
139 18
            $exclusionStrategies[] = $customExclusionStrategy;
140 49
        }
141
142 63
        return $exclusionStrategies;
143
    }
144
}
145