Completed
Pull Request — master (#743)
by Asmir
03:52
created

Context::getExclusionStrategy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * Copyright 2016 Johannes M. Schmitt <[email protected]>
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace JMS\Serializer;
20
21
use JMS\Serializer\Exception\LogicException;
22
use JMS\Serializer\Exception\RuntimeException;
23
use JMS\Serializer\Exclusion\DepthExclusionStrategy;
24
use JMS\Serializer\Exclusion\DisjunctExclusionStrategy;
25
use JMS\Serializer\Exclusion\ExclusionStrategyInterface;
26
use JMS\Serializer\Exclusion\GroupsExclusionStrategy;
27
use JMS\Serializer\Exclusion\VersionExclusionStrategy;
28
use JMS\Serializer\Metadata\ClassMetadata;
29
use JMS\Serializer\Metadata\PropertyMetadata;
30
use Metadata\MetadataFactory;
31
use Metadata\MetadataFactoryInterface;
32
33
abstract class Context
34
{
35
    /**
36
     * @var array
37
     */
38
    private $attributes = array();
39
40
    private $format;
41
42
    /** @var SerializationVisitorInterface|DeserializationVisitorInterface */
43
    private $visitor;
44
45
    /** @var GraphNavigatorInterface */
46
    private $navigator;
47
48
    /** @var MetadataFactory */
49
    private $metadataFactory;
50
51
    /** @var DisjunctExclusionStrategy */
52
    private $exclusionStrategy;
53
54
    /** @var boolean */
55
    private $serializeNull = false;
56
57
    private $initialized = false;
58
59
    /** @var \SplStack */
60
    private $metadataStack;
61
62 422
    public function __construct()
63
    {
64 422
        $this->exclusionStrategy = new DisjunctExclusionStrategy();
65 422
    }
66
67
    /**
68
     * @param string $format
69
     */
70 371
    public function initialize($format, $visitor, GraphNavigatorInterface $navigator, MetadataFactoryInterface $factory)
71
    {
72 371
        if ($this->initialized) {
73
            throw new LogicException('This context was already initialized, and cannot be re-used.');
74
        }
75
76 371
        $this->initialized = true;
77 371
        $this->format = $format;
78 371
        $this->visitor = $visitor;
79 371
        $this->navigator = $navigator;
80 371
        $this->metadataFactory = $factory;
0 ignored issues
show
Documentation Bug introduced by
$factory is of type object<Metadata\MetadataFactoryInterface>, but the property $metadataFactory was declared to be of type object<Metadata\MetadataFactory>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
81 371
        $this->metadataStack = new \SplStack();
82 371
    }
83
84
    public function accept($data, array $type = null)
85
    {
86
        return $this->navigator->accept($data, $type, $this);
87
    }
88
89 15
    public function getMetadataFactory()
90
    {
91 15
        return $this->metadataFactory;
92
    }
93
94 371
    public function getVisitor()
95
    {
96 371
        return $this->visitor;
97
    }
98
99 3
    public function getNavigator()
100
    {
101 3
        return $this->navigator;
102
    }
103
104 228
    public function getExclusionStrategy()
105
    {
106 228
        return $this->exclusionStrategy;
107
    }
108
109 44
    public function getAttribute($key)
110
    {
111 44
        return $this->attributes[$key];
112
    }
113
114 353
    public function hasAttribute($key)
115
    {
116 353
        return isset($this->attributes[$key]);
117
    }
118
119 8
    public function setAttribute($key, $value)
120
    {
121 8
        $this->assertMutable();
122 8
        $this->attributes[$key] = $value;
123
124 8
        return $this;
125
    }
126
127 35
    private function assertMutable()
128
    {
129 35
        if (!$this->initialized) {
130 35
            return;
131
        }
132
133
        throw new LogicException('This context was already initialized and is immutable; you cannot modify it anymore.');
134
    }
135
136 27
    public function addExclusionStrategy(ExclusionStrategyInterface $strategy)
137
    {
138 27
        $this->assertMutable();
139
140 27
        $this->exclusionStrategy->addStrategy($strategy);
141
142 27
        return $this;
143
    }
144
145
    /**
146
     * @param integer $version
147
     */
148 3
    public function setVersion($version)
149
    {
150 3
        if (null === $version) {
151
            throw new LogicException('The version must not be null.');
152
        }
153
154 3
        $this->attributes['version'] = $version;
155 3
        $this->addExclusionStrategy(new VersionExclusionStrategy($version));
156
157 3
        return $this;
158
    }
159
160
    /**
161
     * @param array|string $groups
162
     */
163 14
    public function setGroups($groups)
164
    {
165 14
        if (empty($groups)) {
166
            throw new LogicException('The groups must not be empty.');
167
        }
168
169 14
        $this->attributes['groups'] = (array)$groups;
170 14
        $this->addExclusionStrategy(new GroupsExclusionStrategy((array)$groups));
171
172 14
        return $this;
173
    }
174
175 3
    public function enableMaxDepthChecks()
176
    {
177 3
        $this->addExclusionStrategy(new DepthExclusionStrategy());
178
179 3
        return $this;
180
    }
181
182
    /**
183
     * Set if NULLs should be serialized (TRUE) ot not (FALSE)
184
     *
185
     * @param bool $bool
186
     * @return $this
187
     */
188 20
    public function setSerializeNull($bool)
189
    {
190 20
        $this->serializeNull = (boolean)$bool;
191
192 20
        return $this;
193
    }
194
195
    /**
196
     * Returns TRUE when NULLs should be serialized
197
     * Returns FALSE when NULLs should not be serialized
198
     * Returns NULL when NULLs should not be serialized,
199
     * but the user has not explicitly decided to use this policy
200
     *
201
     * @return bool|null
202
     */
203 53
    public function shouldSerializeNull()
204
    {
205 53
        return $this->serializeNull;
206
    }
207
208
    /**
209
     * @return string
210
     */
211 256
    public function getFormat()
212
    {
213 256
        return $this->format;
214
    }
215
216 219
    public function pushClassMetadata(ClassMetadata $metadata)
217
    {
218 219
        $this->metadataStack->push($metadata);
219 219
    }
220
221 218
    public function pushPropertyMetadata(PropertyMetadata $metadata)
222
    {
223 218
        $this->metadataStack->push($metadata);
224 218
    }
225
226 214
    public function popPropertyMetadata()
227
    {
228 214
        $metadata = $this->metadataStack->pop();
229
230 214
        if (!$metadata instanceof PropertyMetadata) {
231
            throw new RuntimeException('Context metadataStack not working well');
232
        }
233 214
    }
234
235 213
    public function popClassMetadata()
236
    {
237 213
        $metadata = $this->metadataStack->pop();
238
239 213
        if (!$metadata instanceof ClassMetadata) {
240
            throw new RuntimeException('Context metadataStack not working well');
241
        }
242 213
    }
243
244 9
    public function getMetadataStack()
245
    {
246 9
        return $this->metadataStack;
247
    }
248
249
250
    abstract public function getDepth();
251
252
    /**
253
     * @return integer
254
     */
255
    abstract public function getDirection();
256
}
257