RoleDescriptor   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 348
Duplicated Lines 5.17 %

Coupling/Cohesion

Components 3
Dependencies 3

Test Coverage

Coverage 96.55%

Importance

Changes 0
Metric Value
dl 18
loc 348
c 0
b 0
f 0
wmc 36
lcom 3
cbo 3
ccs 112
cts 116
cp 0.9655
rs 9.52

24 Methods

Rating   Name   Duplication   Size   Complexity  
A setCacheDuration() 0 8 1
A getCacheDuration() 0 4 1
A addContactPerson() 9 9 2
A getAllContactPersons() 0 4 1
A setErrorURL() 0 6 1
A getErrorURL() 0 4 1
A setID() 0 6 1
A getID() 0 4 1
A addKeyDescriptor() 0 9 2
A getAllKeyDescriptors() 0 4 1
A getAllKeyDescriptorsByUse() 0 11 3
A getFirstKeyDescriptor() 0 12 5
A addOrganization() 9 9 2
A getAllOrganizations() 0 4 1
A setProtocolSupportEnumeration() 0 6 1
A getProtocolSupportEnumeration() 0 4 1
A addSignature() 0 9 2
A getAllSignatures() 0 4 1
A setValidUntil() 0 6 1
A getValidUntilString() 0 8 2
A getValidUntilTimestamp() 0 4 1
A getValidUntilDateTime() 0 8 2
A serialize() 0 12 1
A deserialize() 0 40 1

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
/*
4
 * This file is part of the LightSAML-Core package.
5
 *
6
 * (c) Milos Tomic <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace LightSaml\Model\Metadata;
13
14
use LightSaml\Helper;
15
use LightSaml\Model\Context\DeserializationContext;
16
use LightSaml\Model\Context\SerializationContext;
17
use LightSaml\Model\AbstractSamlModel;
18
use LightSaml\Model\XmlDSig\Signature;
19
use LightSaml\SamlConstants;
20
21
abstract class RoleDescriptor extends AbstractSamlModel
22
{
23
    /** @var string|null */
24
    protected $id;
25
26
    /** @var int|null */
27
    protected $validUntil;
28
29
    /** @var string|null */
30
    protected $cacheDuration;
31
32
    /** @var string */
33
    protected $protocolSupportEnumeration = SamlConstants::PROTOCOL_SAML2;
34
35
    /** @var string|null */
36
    protected $errorURL;
37
38
    /** @var Signature[]|null */
39
    protected $signatures;
40
41
    /** @var KeyDescriptor[]|null */
42
    protected $keyDescriptors;
43
44
    /** @var Organization[]|null */
45
    protected $organizations;
46
47
    /** @var ContactPerson[]|null */
48
    protected $contactPersons;
49
50
    /**
51
     * @param null|string $cacheDuration
52
     *
53
     * @throws \InvalidArgumentException
54
     *
55
     * @return RoleDescriptor
56
     */
57 2
    public function setCacheDuration($cacheDuration)
58
    {
59 2
        Helper::validateDurationString($cacheDuration);
60
61 1
        $this->cacheDuration = $cacheDuration;
62
63 1
        return $this;
64
    }
65
66
    /**
67
     * @return null|string
68
     */
69 5
    public function getCacheDuration()
70
    {
71 5
        return $this->cacheDuration;
72
    }
73
74
    /**
75
     * @param ContactPerson $contactPerson
76
     *
77
     * @return RoleDescriptor
78
     */
79 2 View Code Duplication
    public function addContactPerson(ContactPerson $contactPerson)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
80
    {
81 2
        if (false == is_array($this->contactPersons)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
82 2
            $this->contactPersons = array();
83
        }
84 2
        $this->contactPersons[] = $contactPerson;
85
86 2
        return $this;
87
    }
88
89
    /**
90
     * @return \LightSaml\Model\Metadata\ContactPerson[]|null
91
     */
92 5
    public function getAllContactPersons()
93
    {
94 5
        return $this->contactPersons;
95
    }
96
97
    /**
98
     * @param null|string $errorURL
99
     *
100
     * @return RoleDescriptor
101
     */
102 2
    public function setErrorURL($errorURL)
103
    {
104 2
        $this->errorURL = (string) $errorURL;
105
106 2
        return $this;
107
    }
108
109
    /**
110
     * @return null|string
111
     */
112 5
    public function getErrorURL()
113
    {
114 5
        return $this->errorURL;
115
    }
116
117
    /**
118
     * @param null|string $id
119
     *
120
     * @return RoleDescriptor
121
     */
122 2
    public function setID($id)
123
    {
124 2
        $this->id = (string) $id;
125
126 2
        return $this;
127
    }
128
129
    /**
130
     * @return null|string
131
     */
132 5
    public function getID()
133
    {
134 5
        return $this->id;
135
    }
136
137
    /**
138
     * @param KeyDescriptor $keyDescriptor
139
     *
140
     * @return RoleDescriptor
141
     */
142 43
    public function addKeyDescriptor(KeyDescriptor $keyDescriptor)
143
    {
144 43
        if (false == is_array($this->keyDescriptors)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
145 43
            $this->keyDescriptors = array();
146
        }
147 43
        $this->keyDescriptors[] = $keyDescriptor;
148
149 43
        return $this;
150
    }
151
152
    /**
153
     * @return \LightSaml\Model\Metadata\KeyDescriptor[]|null
154
     */
155 16
    public function getAllKeyDescriptors()
156
    {
157 16
        return $this->keyDescriptors;
158
    }
159
160
    /**
161
     * @param string $use
162
     *
163
     * @return KeyDescriptor[]
164
     */
165 1
    public function getAllKeyDescriptorsByUse($use)
166
    {
167 1
        $result = array();
168 1
        foreach ($this->getAllKeyDescriptors() as $kd) {
0 ignored issues
show
Bug introduced by
The expression $this->getAllKeyDescriptors() of type array<integer,object<Lig...ta\KeyDescriptor>>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
169 1
            if ($kd->getUse() == $use) {
170 1
                $result[] = $kd;
171
            }
172
        }
173
174 1
        return $result;
175
    }
176
177
    /**
178
     * @param string|null $use
179
     *
180
     * @return KeyDescriptor|null
181
     */
182 2
    public function getFirstKeyDescriptor($use = null)
183
    {
184 2
        if ($this->getAllKeyDescriptors()) {
185 1
            foreach ($this->getAllKeyDescriptors() as $kd) {
186 1
                if (null == $use || $kd->getUse() == $use) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $use of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
187 1
                    return $kd;
188
                }
189
            }
190
        }
191
192 1
        return;
193
    }
194
195
    /**
196
     * @param Organization $organization
197
     *
198
     * @return RoleDescriptor
199
     */
200 2 View Code Duplication
    public function addOrganization(Organization $organization)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
201
    {
202 2
        if (false == is_array($this->organizations)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
203 2
            $this->organizations = array();
204
        }
205 2
        $this->organizations[] = $organization;
206
207 2
        return $this;
208
    }
209
210
    /**
211
     * @return Organization[]|null
212
     */
213 5
    public function getAllOrganizations()
214
    {
215 5
        return $this->organizations;
216
    }
217
218
    /**
219
     * @param string $protocolSupportEnumeration
220
     *
221
     * @return RoleDescriptor
222
     */
223 41
    public function setProtocolSupportEnumeration($protocolSupportEnumeration)
224
    {
225 41
        $this->protocolSupportEnumeration = (string) $protocolSupportEnumeration;
226
227 41
        return $this;
228
    }
229
230
    /**
231
     * @return string
232
     */
233 6
    public function getProtocolSupportEnumeration()
234
    {
235 6
        return $this->protocolSupportEnumeration;
236
    }
237
238
    /**
239
     * @param \LightSaml\Model\XmlDSig\Signature $signature
240
     *
241
     * @return RoleDescriptor
242
     */
243 1
    public function addSignature(Signature $signature)
244
    {
245 1
        if (false == is_array($this->signatures)) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
246 1
            $this->signatures = array();
247
        }
248 1
        $this->signatures[] = $signature;
249
250 1
        return $this;
251
    }
252
253
    /**
254
     * @return \LightSaml\Model\XmlDSig\Signature[]|null
255
     */
256 5
    public function getAllSignatures()
257
    {
258 5
        return $this->signatures;
259
    }
260
261
    /**
262
     * @param int|null $validUntil
263
     *
264
     * @return RoleDescriptor
265
     */
266 4
    public function setValidUntil($validUntil)
267
    {
268 4
        $this->validUntil = Helper::getTimestampFromValue($validUntil);
269
270 4
        return $this;
271
    }
272
273
    /**
274
     * @return string
275
     */
276 5
    public function getValidUntilString()
277
    {
278 5
        if ($this->validUntil) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->validUntil of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
279 1
            return Helper::time2string($this->validUntil);
280
        }
281
282 4
        return;
283
    }
284
285
    /**
286
     * @return int
287
     */
288 3
    public function getValidUntilTimestamp()
289
    {
290 3
        return $this->validUntil;
291
    }
292
293
    /**
294
     * @return \DateTime|null
295
     */
296
    public function getValidUntilDateTime()
297
    {
298
        if ($this->validUntil) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->validUntil of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
299
            return new \DateTime('@'.$this->validUntil);
300
        }
301
302
        return null;
303
    }
304
305
    /**
306
     * @param \DOMNode             $parent
307
     * @param SerializationContext $context
308
     *
309
     * @return void
310
     */
311 4
    public function serialize(\DOMNode $parent, SerializationContext $context)
312
    {
313 4
        $this->attributesToXml(
314 4
            array('protocolSupportEnumeration', 'ID', 'validUntil', 'cacheDuration', 'errorURL'),
315 4
            $parent
0 ignored issues
show
Compatibility introduced by
$parent of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
316
        );
317
318 4
        $this->manyElementsToXml($this->getAllSignatures(), $parent, $context, null);
319 4
        $this->manyElementsToXml($this->getAllKeyDescriptors(), $parent, $context, null);
320 4
        $this->manyElementsToXml($this->getAllOrganizations(), $parent, $context, null);
321 4
        $this->manyElementsToXml($this->getAllContactPersons(), $parent, $context, null);
322 4
    }
323
324
    /**
325
     * @param \DOMNode               $node
326
     * @param DeserializationContext $context
327
     */
328 40
    public function deserialize(\DOMNode $node, DeserializationContext $context)
329
    {
330 40
        $this->attributesFromXml(
331 40
            $node,
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
332 40
            array('protocolSupportEnumeration', 'ID', 'validUntil', 'cacheDuration', 'errorURL')
333
        );
334
335 40
        $this->manyElementsFromXml(
336 40
            $node,
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
337 40
            $context,
338 40
            'Signature',
339 40
            'ds',
340 40
            'LightSaml\Model\XmlDSig\Signature',
341 40
            'addSignature'
342
        );
343 40
        $this->manyElementsFromXml(
344 40
            $node,
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
345 40
            $context,
346 40
            'KeyDescriptor',
347 40
            'md',
348 40
            'LightSaml\Model\Metadata\KeyDescriptor',
349 40
            'addKeyDescriptor'
350
        );
351 40
        $this->manyElementsFromXml(
352 40
            $node,
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
353 40
            $context,
354 40
            'Organization',
355 40
            'md',
356 40
            'LightSaml\Model\Metadata\Organization',
357 40
            'addOrganization'
358
        );
359 40
        $this->manyElementsFromXml(
360 40
            $node,
0 ignored issues
show
Compatibility introduced by
$node of type object<DOMNode> is not a sub-type of object<DOMElement>. It seems like you assume a child class of the class DOMNode to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
361 40
            $context,
362 40
            'ContactPerson',
363 40
            'md',
364 40
            'LightSaml\Model\Metadata\ContactPerson',
365 40
            'addContactPerson'
366
        );
367 40
    }
368
}
369