Completed
Pull Request — master (#3)
by Eric
160:09 queued 158:23
created

Serializer::createExclusionStrategies()   C

Complexity

Conditions 12
Paths 128

Size

Total Lines 54
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 54
ccs 39
cts 39
cp 1
rs 6.0988
c 0
b 0
f 0
cc 12
eloc 32
nc 128
nop 1
crap 12

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 100
    public function __construct(SerializerInterface $serializer)
38
    {
39 100
        $this->serializer = $serializer;
40 100
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45 90
    public function serialize($data, $format, FOSContext $context)
46
    {
47 90
        return $this->serializer->serialize($data, $format, $this->convertContext($context));
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 90
    public function deserialize($data, $type, $format, FOSContext $context)
54
    {
55 90
        return $this->serializer->deserialize($data, $type, $format, $this->convertContext($context));
56
    }
57
58
    /**
59
     * @param FOSContext $fosContext
60
     *
61
     * @return Context
62
     */
63 90
    private function convertContext(FOSContext $fosContext)
64
    {
65 90
        $context = new Context();
66 90
        $context->addOptions($fosContext->getAttributes());
67
68 90
        if ($fosContext->getSerializeNull() !== null) {
69 10
            $context->setIgnoreNull(!$fosContext->getSerializeNull());
70 8
        }
71
72 90
        $exclusionStrategies = $this->createExclusionStrategies($fosContext);
73
74 70
        if (!empty($exclusionStrategies)) {
75 50
            $exclusionStrategy = count($exclusionStrategies) > 1
76 42
                ? new ChainExclusionStrategy($exclusionStrategies)
77 50
                : array_shift($exclusionStrategies);
78
79 50
            $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 40
        }
81
82 70
        return $context;
83
    }
84
85
    /**
86
     * @param FOSContext $context
87
     *
88
     * @return ExclusionStrategyInterface[]
89
     */
90 90
    private function createExclusionStrategies(FOSContext $context)
91
    {
92 90
        $exclusionStrategies = [];
93
94 90
        $groups = $context->getGroups();
95 90
        $version = $context->getVersion();
96
97 90
        if (!empty($groups)) {
98 10
            $exclusionStrategies[] = new GroupsExclusionStrategy($groups);
99 8
        }
100
101 90
        if (!empty($version)) {
102 10
            $exclusionStrategies[] = new VersionExclusionStrategy($version);
103 8
        }
104
105 90
        if (method_exists($context, 'isMaxDepthEnabled')) {
106 72
            if ($context->isMaxDepthEnabled()) {
107 24
                $exclusionStrategies[] = new MaxDepthExclusionStrategy();
108 6
            }
109 54
        } 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 90
        $customExclusionStrategies = $context->getAttribute($attribute = 'ivory_exclusion_strategies') ?: [];
118
119 90
        if (!is_array($customExclusionStrategies) && !$customExclusionStrategies instanceof \Traversable) {
120 10
            throw new \RuntimeException(sprintf(
121 10
                'The "%s" context attribute must be an array or implement "%s".',
122 8
                $attribute,
123 2
                \Traversable::class
124 8
            ));
125
        }
126
127 80
        foreach ($customExclusionStrategies as $customExclusionStrategy) {
128 30
            if (!$customExclusionStrategy instanceof ExclusionStrategyInterface) {
129 10
                throw new \RuntimeException(sprintf(
130 10
                    'The "%s" context attribute must be an array of "%s", got "%s".',
131 8
                    $attribute,
132 10
                    ExclusionStrategyInterface::class,
133 10
                    is_object($customExclusionStrategy)
134 8
                        ? get_class($customExclusionStrategy)
135 10
                        : gettype($customExclusionStrategy)
136 8
                ));
137
            }
138
139 20
            $exclusionStrategies[] = $customExclusionStrategy;
140 56
        }
141
142 70
        return $exclusionStrategies;
143
    }
144
}
145