Completed
Push — 1.x ( 257780...f31d1d )
by Mikaël
42:33 queued 33:38
created

Struct   C

Complexity

Total Complexity 59

Size/Duplication

Total Lines 365
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 94.48%

Importance

Changes 4
Bugs 0 Features 3
Metric Value
wmc 59
c 4
b 0
f 3
lcom 1
cbo 9
dl 0
loc 365
ccs 137
cts 145
cp 0.9448
rs 6.1904

25 Methods

Rating   Name   Duplication   Size   Complexity  
A getInheritanceStruct() 0 4 1
A getTopInheritance() 0 15 4
A getMeta() 0 5 3
A getReservedMethodsInstance() 0 8 2
A __construct() 0 9 1
A getContextualPart() 0 10 3
A getDocSubPackages() 0 12 3
B isArray() 0 4 5
A getAttributes() 0 9 3
A getAllAttributes() 0 16 4
B addInheritanceAttributes() 0 11 5
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 getIsRestriction() 0 4 1
A setIsRestriction() 0 5 1
A getIsStruct() 0 4 1
A setIsStruct() 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

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
    private $attributes;
34
    /**
35
     * Is the struct a restriction with defined values  ?
36
     * @var bool
37
     */
38
    private $isRestriction = false;
39
    /**
40
     * If the struct is a restriction with values, then store values
41
     * @var StructValueContainer
42
     */
43
    private $values;
44
    /**
45
     * Define if the urrent struct is a concrete struct or just a virtual struct to store meta informations
46
     * @var bool
47
     */
48
    private $isStruct = false;
49
    /**
50
     * Main constructor
51
     * @see AbstractModel::__construct()
52
     * @uses Struct::setIsStruct()
53
     * @param Generator $generator
54
     * @param string $name the original name
55
     * @param bool $isStruct defines if it's a real sruct or not
56
     * @param bool $isRestriction defines if it's an enumeration or not
57
     */
58 536
    public function __construct(Generator $generator, $name, $isStruct = true, $isRestriction = false)
59
    {
60 536
        parent::__construct($generator, $name);
61 536
        $this
62 536
            ->setIsStruct($isStruct)
63 536
            ->setIsRestriction($isRestriction)
64 536
            ->setAttributes(new StructAttributeContainer($generator))
65 536
            ->setValues(new StructValueContainer($generator));
66 536
    }
67
    /**
68
     * Returns the contextual part of the class name for the package
69
     * @see AbstractModel::getContextualPart()
70
     * @uses Struct::getIsRestriction()
71
     * @return string
72
     */
73 256
    public function getContextualPart()
74
    {
75 256
        $part = $this->getGenerator()->getOptionStructsFolder();
76 256
        if ($this->getIsRestriction()) {
77 88
            $part = $this->getGenerator()->getOptionEnumsFolder();
78 256
        } elseif ($this->isArray()) {
79 48
            $part = $this->getGenerator()->getOptionArraysFolder();
80 48
        }
81 256
        return $part;
82
    }
83
    /**
84
     * Returns the sub package name which the model belongs to
85
     * Must be overridden by sub classes
86
     * @see AbstractModel::getDocSubPackages()
87
     * @uses Struct::getIsRestriction()
88
     * @return array
89
     */
90 140
    public function getDocSubPackages()
91
    {
92 140
        $package = self::DOC_SUB_PACKAGE_STRUCTS;
93 140
        if ($this->getIsRestriction()) {
94 52
            $package = self::DOC_SUB_PACKAGE_ENUMERATIONS;
95 140
        } elseif ($this->isArray()) {
96 28
            $package = self::DOC_SUB_PACKAGE_ARRAYS;
97 28
        }
98
        return array(
99 140
            $package,
100 140
        );
101
    }
102
    /**
103
     * Returns true if the current struct is a collection of values (like an array)
104
     * @uses AbstractModel::getName()
105
     * @uses Struct::countOwnAttributes()
106
     * @return bool
107
     */
108 284
    public function isArray()
109
    {
110 284
        return ((($this->getIsStruct() && $this->countOwnAttributes() === 1) || (!$this->getIsStruct() && $this->countOwnAttributes() <= 1)) && stripos($this->getName(), 'array') !== false);
111
    }
112
    /**
113
     * Returns the attributes of the struct and potentially from the parent class
114
     * @uses AbstractModel::getInheritance()
115
     * @uses Struct::getIsStruct()
116
     * @uses Struct::getAttributes()
117
     * @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.
118
     * @param bool $requiredFirst places the required attributes first, then the not required in order to have the _contrust method with the required attribute at first
119
     * @return StructAttributeContainer
120
     */
121 296
    public function getAttributes($includeInheritanceAttributes = false, $requiredFirst = false)
122
    {
123 296
        if ($includeInheritanceAttributes === false && $requiredFirst === false) {
124 296
            $attributes = $this->attributes;
125 296
        } else {
126 104
            $attributes = $this->getAllAttributes($includeInheritanceAttributes, $requiredFirst);
127
        }
128 296
        return $attributes;
129
    }
130
    /**
131
     * @param bool $includeInheritanceAttributes
132
     * @param bool $requiredFirst
133
     * @return StructAttributeContainer
134
     */
135 104
    protected function getAllAttributes($includeInheritanceAttributes, $requiredFirst)
136
    {
137 104
        $allAttributes = new StructAttributeContainer($this->getGenerator());
138 104
        if ($includeInheritanceAttributes === true) {
139 4
            $this->addInheritanceAttributes($allAttributes);
140 4
        }
141 104
        foreach ($this->attributes as $attribute) {
142 104
            $allAttributes->add($attribute);
143 104
        }
144 104
        if ($requiredFirst === true) {
145 104
            $attributes = $this->putRequiredFirst($allAttributes);
146 104
        } else {
147
            $attributes = $allAttributes;
148
        }
149 104
        return $attributes;
150
    }
151
    /**
152
     * @param StructAttributeContainer $attributes
153
     */
154 4
    protected function addInheritanceAttributes(StructAttributeContainer $attributes)
155
    {
156 4
        if ($this->getInheritance() != '' && ($model = $this->getInheritanceStruct()) instanceof Struct) {
157
            while ($model->getIsStruct()) {
158
                foreach ($model->getAttributes() as $attribute) {
159
                    $attributes->add($attribute);
160
                }
161
                $model = $this->getGenerator()->getStruct($model->getInheritance());
162
            }
163
        }
164 4
    }
165
    /**
166
     * @param StructAttributeContainer $allAttributes
167
     * @return StructAttributeContainer
168
     */
169 104
    protected function putRequiredFirst(StructAttributeContainer $allAttributes)
170
    {
171 104
        $attributes = new StructAttributeContainer($this->getGenerator());
172 104
        $requiredAttributes = new StructAttributeContainer($this->getGenerator());
173 104
        $notRequiredAttributes = new StructAttributeContainer($this->getGenerator());
174 104
        foreach ($allAttributes as $attribute) {
175 104
            if ($attribute->isRequired()) {
176 28
                $requiredAttributes->add($attribute);
177 28
            } else {
178 96
                $notRequiredAttributes->add($attribute);
179
            }
180 104
        }
181 104
        foreach ($requiredAttributes as $attribute) {
182 28
            $attributes->add($attribute);
183 104
        }
184 104
        foreach ($notRequiredAttributes as $attribute) {
185 96
            $attributes->add($attribute);
186 104
        }
187 104
        unset($requiredAttributes, $notRequiredAttributes);
188 104
        return $attributes;
189
    }
190
    /**
191
     * Returns the number of own attributes
192
     * @uses Struct::getAttributes()
193
     * @return int
194
     */
195 284
    public function countOwnAttributes()
196
    {
197 284
        return $this->getAttributes(false, false)->count();
198
    }
199
    /**
200
     * Sets the attributes of the struct
201
     * @param StructAttributeContainer $structAttributeContainer
202
     * @return Struct
203
     */
204 536
    public function setAttributes(StructAttributeContainer $structAttributeContainer)
205
    {
206 536
        $this->attributes = $structAttributeContainer;
207 536
        return $this;
208
    }
209
    /**
210
     * Adds attribute based on its original name
211
     * @throws \InvalidArgumentException
212
     * @param string $attributeName the attribute name
213
     * @param string $attributeType the attribute type
214
     * @return Struct
215
     */
216 480
    public function addAttribute($attributeName, $attributeType)
217
    {
218 480
        if (empty($attributeName) || empty($attributeType)) {
219 8
            throw new \InvalidArgumentException(sprintf('Attribute name "%s" and/or attribute type "%s" is invalid for Struct "%s"', $attributeName, $attributeType, $this->getName()), __LINE__);
220
        }
221 472
        if ($this->attributes->getStructAttributeByName($attributeName) === null) {
222 468
            $structAttribute = new StructAttribute($this->getGenerator(), $attributeName, $attributeType, $this);
223 468
            $this->attributes->add($structAttribute);
224 468
        }
225 472
        return $this;
226
    }
227
    /**
228
     * Returns the attribute by its name, otherwise null
229
     * @uses Struct::getAttributes()
230
     * @param string $attributeName the original attribute name
231
     * @return StructAttribute|null
232
     */
233 336
    public function getAttribute($attributeName)
234
    {
235 336
        return $this->attributes->getStructAttributeByName($attributeName);
236
    }
237
    /**
238
     * Returns the isRestriction value
239
     * @return bool
240
     */
241 288
    public function getIsRestriction()
242
    {
243 288
        return $this->isRestriction;
244
    }
245
    /**
246
     * Sets the isRestriction value
247
     * @param bool $isRestriction
248
     * @return Struct
249
     */
250 536
    public function setIsRestriction($isRestriction = true)
251
    {
252 536
        $this->isRestriction = $isRestriction;
253 536
        return $this;
254
    }
255
    /**
256
     * Returns the isStruct value
257
     * @return bool
258
     */
259 312
    public function getIsStruct()
260
    {
261 312
        return $this->isStruct;
262
    }
263
    /**
264
     * Sets the isStruct value
265
     * @param bool $isStruct
266
     * @return Struct
267
     */
268 536
    public function setIsStruct($isStruct = true)
269
    {
270 536
        $this->isStruct = $isStruct;
271 536
        return $this;
272
    }
273
    /**
274
     * Returns the values for an enumeration
275
     * @return StructValueContainer
276
     */
277 300
    public function getValues()
278
    {
279 300
        return $this->values;
280
    }
281
    /**
282
     * Sets the values for an enumeration
283
     * @param StructValueContainer $structValueContainer
284
     * @return Struct
285
     */
286 536
    private function setValues(StructValueContainer $structValueContainer)
287
    {
288 536
        $this->values = $structValueContainer;
289 536
        return $this;
290
    }
291
    /**
292
     * Adds value to values array
293
     * @uses Struct::getValue()
294
     * @uses Struct::getValues()
295
     * @param mixed $value the original value
296
     * @return Struct
297
     */
298 304
    public function addValue($value)
299
    {
300 304
        if ($this->getValue($value) === null) {
301 300
            $this->values->add(new StructValue($this->getGenerator(), $value, $this->getValues()->count(), $this));
302 300
            $this->setIsRestriction(true);
303 300
            $this->setIsStruct(true);
304 300
        }
305 304
        return $this;
306
    }
307
    /**
308
     * Gets the value object for the given value
309
     * @uses Struct::getValues()
310
     * @uses AbstractModel::getName()
311
     * @param string $value Value name
312
     * @return StructValue|null
313
     */
314 304
    public function getValue($value)
315
    {
316 304
        return $this->values->getStructValueByName($value);
317
    }
318
    /**
319
     * Allows to define from which class the curent model extends
320
     * @param bool $short
321
     * @return string
322
     */
323 132
    public function getExtends($short = false)
324
    {
325 132
        $extends = '';
326 132
        if ($this->isArray()) {
327 28
            $extends = $this->getGenerator()->getOptionStructArrayClass();
328 132
        } elseif (!$this->getIsRestriction()) {
329 84
            $extends = $this->getGenerator()->getOptionStructClass();
330 84
        }
331 132
        return $short ? Utils::removeNamespace($extends) : $extends;
332
    }
333
    /**
334
     * @return Struct|null
335
     */
336 168
    public function getInheritanceStruct()
337
    {
338 168
        return $this->getGenerator()->getStruct(str_replace('[]', '', $this->getInheritance()));
339
    }
340
    /**
341
     * @return Struct|null
342
     */
343 96
    public function getTopInheritance()
344
    {
345 96
        $inheritance = $this->getInheritance();
346 96
        if (!empty($inheritance)) {
347 44
            $struct = $this->getInheritanceStruct();
348 44
            while ($struct instanceof Struct) {
349 36
                $structInheritance = $struct->getInheritance();
350 36
                if (!empty($structInheritance)) {
351 16
                    $inheritance = $structInheritance;
352 16
                }
353 36
                $struct = $struct->getInheritanceStruct();
354 36
            }
355 44
        }
356 96
        return $inheritance;
357
    }
358
    /**
359
     * @see \WsdlToPhp\PackageGenerator\Model\AbstractModel::getMeta()
360
     * @return string[]
361
     */
362 160
    public function getMeta()
363
    {
364 160
        $inheritanceStruct = $this->getInheritanceStruct();
365 160
        return array_merge_recursive(parent::getMeta(), ($inheritanceStruct && !$inheritanceStruct->getIsStruct()) ? $inheritanceStruct->getMeta() : array());
366
    }
367
    /**
368
     * @param $filename
369
     * @return StructReservedMethod|StructArrayReservedMethod
370
     */
371 116
    public function getReservedMethodsInstance($filename = null)
372
    {
373 116
        $instance = StructReservedMethod::instance($filename);
374 116
        if ($this->isArray()) {
375 32
            $instance = StructArrayReservedMethod::instance($filename);
376 32
        }
377 116
        return $instance;
378
    }
379
}
380