Completed
Push — master ( 06621f...b41c10 )
by Mikaël
30:47
created

Struct   C

Complexity

Total Complexity 71

Size/Duplication

Total Lines 436
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 95.35%

Importance

Changes 0
Metric Value
wmc 71
lcom 1
cbo 9
dl 0
loc 436
ccs 164
cts 172
cp 0.9535
rs 5.5904
c 0
b 0
f 0

32 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A getContextualPart() 0 10 3
A getDocSubPackages() 0 12 3
C isArray() 0 4 7
A getAttributes() 0 9 3
A getAllAttributes() 0 16 4
B addInheritanceAttributes() 0 11 6
B putRequiredFirst() 0 21 5
A countOwnAttributes() 0 4 1
A setAttributes() 0 5 1
A addAttribute() 0 11 4
A getAttribute() 0 4 1
A getAttributeByCleanName() 0 4 1
A isRestriction() 0 4 1
A setRestriction() 0 5 1
A isStruct() 0 4 1
A setStruct() 0 5 1
A getValues() 0 4 1
A setValues() 0 5 1
A addValue() 0 9 2
A getValue() 0 4 1
A getExtends() 0 10 4
A getInheritanceStruct() 0 4 1
A getTopInheritance() 0 15 4
A getMeta() 0 5 3
A getReservedMethodsInstance() 0 8 2
A getTypes() 0 4 1
A isUnion() 0 4 1
A setTypes() 0 5 1
A toJsonSerialize() 0 10 1
A setAttributesFromSerializedJson() 0 6 2
A setValuesFromSerializedJson() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like Struct often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Struct, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace WsdlToPhp\PackageGenerator\Model;
4
5
use WsdlToPhp\PackageGenerator\Generator\Utils;
6
use WsdlToPhp\PackageGenerator\Container\Model\StructValue as StructValueContainer;
7
use WsdlToPhp\PackageGenerator\Container\Model\StructAttribute as StructAttributeContainer;
8
use WsdlToPhp\PackageGenerator\Generator\Generator;
9
use WsdlToPhp\PackageGenerator\ConfigurationReader\StructReservedMethod;
10
use WsdlToPhp\PackageGenerator\ConfigurationReader\StructArrayReservedMethod;
11
12
/**
13
 * Class Struct stands for an available struct described in the WSDL
14
 */
15
class Struct extends AbstractModel
16
{
17
    /**
18
     * @var string
19
     */
20
    const DOC_SUB_PACKAGE_STRUCTS = 'Structs';
21
    /**
22
     * @var string
23
     */
24
    const DOC_SUB_PACKAGE_ENUMERATIONS = 'Enumerations';
25
    /**
26
     * @var string
27
     */
28
    const DOC_SUB_PACKAGE_ARRAYS = 'Arrays';
29
    /**
30
     * Attributes of the struct
31
     * @var StructAttributeContainer
32
     */
33
    protected $attributes;
34
    /**
35
     * Is the struct a restriction with defined values  ?
36
     * @var bool
37
     */
38
    protected $isRestriction = false;
39
    /**
40
     * If the struct is a restriction with values, then store values
41
     * @var StructValueContainer
42
     */
43
    protected $values;
44
    /**
45
     * If the struct is a union with types, then store types
46
     * @var string[]
47
     */
48
    protected $types;
49
    /**
50
     * Define if the current struct is a concrete struct or just a virtual struct to store meta informations
51
     * @var bool
52
     */
53
    protected $isStruct = false;
54
    /**
55
     * Main constructor
56
     * @see AbstractModel::__construct()
57
     * @uses Struct::setStruct()
58
     * @param Generator $generator
59
     * @param string $name the original name
60
     * @param bool $isStruct defines if it's a real struct or not
61
     * @param bool $isRestriction defines if it's an enumeration or not
62
     */
63 1220
    public function __construct(Generator $generator, $name, $isStruct = true, $isRestriction = false)
64
    {
65 1220
        parent::__construct($generator, $name);
66 488
        $this
67 1220
            ->setStruct($isStruct)
68 1220
            ->setRestriction($isRestriction)
69 1220
            ->setAttributes(new StructAttributeContainer($generator))
70 1220
            ->setValues(new StructValueContainer($generator))
71 1220
            ->setTypes([]);
72 1220
    }
73
    /**
74
     * Returns the contextual part of the class name for the package
75
     * @see AbstractModel::getContextualPart()
76
     * @uses Struct::isRestriction()
77
     * @return string
78
     */
79 365
    public function getContextualPart()
80
    {
81 365
        $part = $this->getGenerator()->getOptionStructsFolder();
82 365
        if ($this->isRestriction()) {
83 135
            $part = $this->getGenerator()->getOptionEnumsFolder();
84 338
        } elseif ($this->isArray()) {
85 65
            $part = $this->getGenerator()->getOptionArraysFolder();
86 26
        }
87 365
        return $part;
88
    }
89
    /**
90
     * Returns the sub package name which the model belongs to
91
     * Must be overridden by sub classes
92
     * @see AbstractModel::getDocSubPackages()
93
     * @uses Struct::isRestriction()
94
     * @return array
95
     */
96 205
    public function getDocSubPackages()
97
    {
98 205
        $package = self::DOC_SUB_PACKAGE_STRUCTS;
99 205
        if ($this->isRestriction()) {
100 70
            $package = self::DOC_SUB_PACKAGE_ENUMERATIONS;
101 181
        } elseif ($this->isArray()) {
102 40
            $package = self::DOC_SUB_PACKAGE_ARRAYS;
103 16
        }
104
        return [
105 205
            $package,
106 82
        ];
107
    }
108
    /**
109
     * Returns true if the current struct is a collection of values (like an array)
110
     * @uses AbstractModel::getName()
111
     * @uses Struct::countOwnAttributes()
112
     * @return bool
113
     */
114 405
    public function isArray()
115
    {
116 405
        return ((($this->isStruct() && $this->countOwnAttributes() === 1) || (!$this->isStruct() && $this->countOwnAttributes() <= 1)) && (stripos($this->getName(), 'array') !== false) || (!$this->isStruct() && $this->getMetaValueFirstSet(['arraytype', 'arrayType'], false) !== false));
117
    }
118
    /**
119
     * Returns the attributes of the struct and potentially from the parent class
120
     * @uses AbstractModel::getInheritance()
121
     * @uses Struct::isStruct()
122
     * @uses Struct::getAttributes()
123
     * @param bool $includeInheritanceAttributes include the attributes of parent class, default parent attributes are not included. If true, then the array is an associative array containing and index "attribute" for the StructAttribute object and an index "model" for the Struct object.
124
     * @param bool $requiredFirst places the required attributes first, then the not required in order to have the _construct method with the required attribute at first
125
     * @return StructAttributeContainer
126
     */
127 420
    public function getAttributes($includeInheritanceAttributes = false, $requiredFirst = false)
128
    {
129 420
        if ($includeInheritanceAttributes === false && $requiredFirst === false) {
130 420
            $attributes = $this->attributes;
131 168
        } else {
132 160
            $attributes = $this->getAllAttributes($includeInheritanceAttributes, $requiredFirst);
133
        }
134 420
        return $attributes;
135
    }
136
    /**
137
     * @param bool $includeInheritanceAttributes
138
     * @param bool $requiredFirst
139
     * @return StructAttributeContainer
140
     */
141 160
    protected function getAllAttributes($includeInheritanceAttributes, $requiredFirst)
142
    {
143 160
        $allAttributes = new StructAttributeContainer($this->getGenerator());
144 160
        if ($includeInheritanceAttributes === true) {
145 5
            $this->addInheritanceAttributes($allAttributes);
146 2
        }
147 160
        foreach ($this->attributes as $attribute) {
148 160
            $allAttributes->add($attribute);
149 64
        }
150 160
        if ($requiredFirst === true) {
151 160
            $attributes = $this->putRequiredFirst($allAttributes);
152 64
        } else {
153
            $attributes = $allAttributes;
154
        }
155 160
        return $attributes;
156
    }
157
    /**
158
     * @param StructAttributeContainer $attributes
159
     */
160 5
    protected function addInheritanceAttributes(StructAttributeContainer $attributes)
161
    {
162 5
        if ($this->getInheritance() != '' && ($model = $this->getInheritanceStruct()) instanceof Struct) {
163
            while ($model instanceof Struct && $model->isStruct()) {
164
                foreach ($model->getAttributes() as $attribute) {
165
                    $attributes->add($attribute);
166
                }
167
                $model = $model->getInheritanceStruct();
168
            }
169
        }
170 5
    }
171
    /**
172
     * @param StructAttributeContainer $allAttributes
173
     * @return StructAttributeContainer
174
     */
175 160
    protected function putRequiredFirst(StructAttributeContainer $allAttributes)
176
    {
177 160
        $attributes = new StructAttributeContainer($this->getGenerator());
178 160
        $requiredAttributes = new StructAttributeContainer($this->getGenerator());
179 160
        $notRequiredAttributes = new StructAttributeContainer($this->getGenerator());
180 160
        foreach ($allAttributes as $attribute) {
181 160
            if ($attribute->isRequired()) {
182 40
                $requiredAttributes->add($attribute);
183 16
            } else {
184 156
                $notRequiredAttributes->add($attribute);
185
            }
186 64
        }
187 160
        foreach ($requiredAttributes as $attribute) {
188 40
            $attributes->add($attribute);
189 64
        }
190 160
        foreach ($notRequiredAttributes as $attribute) {
191 150
            $attributes->add($attribute);
192 64
        }
193 160
        unset($requiredAttributes, $notRequiredAttributes);
194 160
        return $attributes;
195
    }
196
    /**
197
     * Returns the number of own attributes
198
     * @uses Struct::getAttributes()
199
     * @return int
200
     */
201 405
    public function countOwnAttributes()
202
    {
203 405
        return $this->getAttributes(false, false)->count();
204
    }
205
    /**
206
     * Sets the attributes of the struct
207
     * @param StructAttributeContainer $structAttributeContainer
208
     * @return Struct
209
     */
210 1220
    public function setAttributes(StructAttributeContainer $structAttributeContainer)
211
    {
212 1220
        $this->attributes = $structAttributeContainer;
213 1220
        return $this;
214
    }
215
    /**
216
     * Adds attribute based on its original name
217
     * @throws \InvalidArgumentException
218
     * @param string $attributeName the attribute name
219
     * @param string $attributeType the attribute type
220
     * @return Struct
221
     */
222 325
    public function addAttribute($attributeName, $attributeType)
223
    {
224 325
        if (empty($attributeName) || empty($attributeType)) {
225 10
            throw new \InvalidArgumentException(sprintf('Attribute name "%s" and/or attribute type "%s" is invalid for Struct "%s"', $attributeName, $attributeType, $this->getName()), __LINE__);
226
        }
227 315
        if ($this->attributes->getStructAttributeByName($attributeName) === null) {
228 315
            $structAttribute = new StructAttribute($this->getGenerator(), $attributeName, $attributeType, $this);
229 315
            $this->attributes->add($structAttribute);
230 126
        }
231 315
        return $this;
232
    }
233
    /**
234
     * Returns the attribute by its name, otherwise null
235
     * @uses Struct::getAttributes()
236
     * @param string $attributeName the original attribute name
237
     * @return StructAttribute|null
238
     */
239 250
    public function getAttribute($attributeName)
240
    {
241 250
        return $this->attributes->getStructAttributeByName($attributeName);
242
    }
243
    /**
244
     * Returns the attribute by its cleaned name, otherwise null
245
     * @uses Struct::getAttributes()
246
     * @param string $attributeCleanName the cleaned attribute name
247
     * @return StructAttribute|null
248
     */
249 75
    public function getAttributeByCleanName($attributeCleanName)
250
    {
251 75
        return $this->attributes->getStructAttributeByCleanName($attributeCleanName);
252
    }
253
    /**
254
     * Returns the isRestriction value
255
     * @return bool
256
     */
257 405
    public function isRestriction()
258
    {
259 405
        return $this->isRestriction;
260
    }
261
    /**
262
     * Sets the isRestriction value
263
     * @param bool $isRestriction
264
     * @return Struct
265
     */
266 1220
    public function setRestriction($isRestriction = true)
267
    {
268 1220
        $this->isRestriction = $isRestriction;
269 1220
        return $this;
270
    }
271
    /**
272
     * Returns the isStruct value
273
     * @return bool
274
     */
275 440
    public function isStruct()
276
    {
277 440
        return $this->isStruct;
278
    }
279
    /**
280
     * Sets the isStruct value
281
     * @param bool $isStruct
282
     * @return Struct
283
     */
284 1220
    public function setStruct($isStruct = true)
285
    {
286 1220
        $this->isStruct = $isStruct;
287 1220
        return $this;
288
    }
289
    /**
290
     * Returns the values for an enumeration
291
     * @return StructValueContainer
292
     */
293 115
    public function getValues()
294
    {
295 115
        return $this->values;
296
    }
297
    /**
298
     * Sets the values for an enumeration
299
     * @param StructValueContainer $structValueContainer
300
     * @return Struct
301
     */
302 1220
    protected function setValues(StructValueContainer $structValueContainer)
303
    {
304 1220
        $this->values = $structValueContainer;
305 1220
        return $this;
306
    }
307
    /**
308
     * Adds value to values array
309
     * @uses Struct::getValue()
310
     * @uses Struct::getValues()
311
     * @param mixed $value the original value
312
     * @return Struct
313
     */
314 80
    public function addValue($value)
315
    {
316 80
        if ($this->getValue($value) === null) {
317 80
            $this->values->add(new StructValue($this->getGenerator(), $value, $this->getValues()->count(), $this));
318 80
            $this->setRestriction(true);
319 80
            $this->setStruct(true);
320 32
        }
321 80
        return $this;
322
    }
323
    /**
324
     * Gets the value object for the given value
325
     * @uses Struct::getValues()
326
     * @uses AbstractModel::getName()
327
     * @param string $value Value name
328
     * @return StructValue|null
329
     */
330 115
    public function getValue($value)
331
    {
332 115
        return $this->values->getStructValueByName($value);
333
    }
334
    /**
335
     * Allows to define from which class the current model extends
336
     * @param bool $short
337
     * @return string
338
     */
339 195
    public function getExtends($short = false)
340
    {
341 195
        $extends = '';
342 195
        if ($this->isArray()) {
343 40
            $extends = $this->getGenerator()->getOptionStructArrayClass();
344 180
        } elseif (!$this->isRestriction()) {
345 135
            $extends = $this->getGenerator()->getOptionStructClass();
346 54
        }
347 195
        return $short ? Utils::removeNamespace($extends) : $extends;
348
    }
349
    /**
350
     * @return Struct|null
351
     */
352 275
    public function getInheritanceStruct()
353
    {
354 275
        return $this->getGenerator()->getStruct(str_replace('[]', '', $this->getInheritance()));
355
    }
356
    /**
357
     * @return string
358
     */
359 175
    public function getTopInheritance()
360
    {
361 175
        $inheritance = $this->getInheritance();
362 175
        if (!empty($inheritance)) {
363 80
            $struct = $this->getInheritanceStruct();
364 80
            while ($struct instanceof Struct) {
365 55
                $structInheritance = $struct->getInheritance();
366 55
                if (!empty($structInheritance)) {
367 25
                    $inheritance = $structInheritance;
368 10
                }
369 55
                $struct = $struct->getInheritanceStruct();
370 22
            }
371 32
        }
372 175
        return $inheritance;
373
    }
374
    /**
375
     * @see \WsdlToPhp\PackageGenerator\Model\AbstractModel::getMeta()
376
     * @return string[]
377
     */
378 265
    public function getMeta()
379
    {
380 265
        $inheritanceStruct = $this->getInheritanceStruct();
381 265
        return array_merge_recursive(parent::getMeta(), ($inheritanceStruct && !$inheritanceStruct->isStruct()) ? $inheritanceStruct->getMeta() : []);
382
    }
383
    /**
384
     * @param $filename
385
     * @return StructReservedMethod|StructArrayReservedMethod
386
     */
387 180
    public function getReservedMethodsInstance($filename = null)
388
    {
389 180
        $instance = StructReservedMethod::instance($filename);
390 180
        if ($this->isArray()) {
391 45
            $instance = StructArrayReservedMethod::instance($filename);
392 18
        }
393 180
        return $instance;
394
    }
395
    /**
396
     * @return string[]
397
     */
398 5
    public function getTypes()
399
    {
400 5
        return $this->types;
401
    }
402
    /**
403
     * @return boolean
404
     */
405 165
    public function isUnion()
406
    {
407 165
        return count($this->types) > 0;
408
    }
409
    /**
410
     * @param string[] $types
411
     * @return Struct
412
     */
413 1220
    public function setTypes($types)
414
    {
415 1220
        $this->types = $types;
416 1220
        return $this;
417
    }
418
    /**
419
     * {@inheritDoc}
420
     * @see \WsdlToPhp\PackageGenerator\Model\AbstractModel::toJsonSerialize()
421
     */
422 5
    protected function toJsonSerialize()
423
    {
424
        return [
425 5
            'attributes' => $this->attributes,
426 5
            'restriction' => $this->isRestriction,
427 5
            'struct' => $this->isStruct,
428 5
            'types' => $this->types,
429 5
            'values' => $this->values,
430 2
        ];
431
    }
432
    /**
433
     * @param array $attributes
434
     */
435 380
    public function setAttributesFromSerializedJson(array $attributes)
436
    {
437 380
        foreach ($attributes as $attribute) {
438 375
            $this->attributes->add(self::instanceFromSerializedJson($this->generator, $attribute)->setOwner($this));
439 152
        }
440 380
    }
441
    /**
442
     * @param array $values
443
     */
444 380
    public function setValuesFromSerializedJson(array $values)
445
    {
446 380
        foreach ($values as $value) {
447 360
            $this->values->add(self::instanceFromSerializedJson($this->generator, $value)->setOwner($this));
448 152
        }
449 380
    }
450
}
451