StructAttribute   B
last analyzed

Complexity

Total Complexity 44

Size/Duplication

Total Lines 215
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 8
Bugs 1 Features 1
Metric Value
eloc 62
c 8
b 1
f 1
dl 0
loc 215
ccs 87
cts 87
cp 1
rs 8.8798
wmc 44

27 Methods

Rating   Name   Duplication   Size   Complexity  
A getSetterName() 0 3 1
A getUniqueName() 0 3 1
A getGetterName() 0 3 1
A getUniqueString() 0 3 1
A setType() 0 5 1
A isList() 0 5 2
A setContainsElements() 0 5 2
A isAChoice() 0 3 1
A getContainsElements() 0 3 1
A setRemovableFromRequest() 0 5 2
A isArray() 0 3 2
A getRemovableFromRequest() 0 3 1
A getInheritanceStructMeta() 0 5 3
A getOwner() 0 3 1
A getReservedMethodsInstance() 0 3 1
A getTypeStructMeta() 0 5 3
A getMeta() 0 3 1
A isTypeStructArray() 0 5 3
A getInheritanceStruct() 0 3 1
A isXml() 0 3 1
A toJsonSerialize() 0 6 1
A isNullable() 0 3 1
A __construct() 0 6 1
A isRequired() 0 8 2
A getTypeStruct() 0 5 2
A getType() 0 12 4
A getDefaultValue() 0 13 3

How to fix   Complexity   

Complex Class

Complex classes like StructAttribute 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.

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 StructAttribute, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace WsdlToPhp\PackageGenerator\Model;
6
7
use WsdlToPhp\PackageGenerator\ConfigurationReader\AbstractReservedWord;
8
use WsdlToPhp\PackageGenerator\Generator\Generator;
9
use WsdlToPhp\PackageGenerator\Generator\Utils;
10
11
/**
12
 * Class StructAttribute stands for an available struct attribute described in the WSDL.
13
 */
14
final class StructAttribute extends AbstractModel
15
{
16
    protected string $type = '';
17
18
    /**
19
     * Defines that this property is not a simple value but an array of values
20
     * Infos at {@link https://www.w3.org/TR/xmlschema-0/#OccurrenceConstraints}.
21
     */
22
    protected bool $containsElements = false;
23
24
    /**
25
     * Defines that this property can be removed from request or not.
26
     * The property can be removed from the request (meaning from the Struct) as soon as the nillable=true && minOccurs=0
27
     * Infos at {@link http://www.w3schools.com/xml/el_element.asp}.
28
     */
29
    protected bool $removableFromRequest = false;
30
31 398
    public function __construct(Generator $generator, string $name, string $type = '', ?Struct $struct = null)
32
    {
33 398
        parent::__construct($generator, $name);
34 398
        $this
35 398
            ->setType($type)
36 398
            ->setOwner($struct)
37 398
        ;
38
    }
39
40 116
    public function getUniqueString(string $string, string $additionalContext = ''): string
41
    {
42 116
        return self::uniqueName($string, spl_object_hash($this->getOwner()).$this->getOwner()->getName().$additionalContext);
43
    }
44
45 116
    public function getUniqueName(string $additionalContext = ''): string
46
    {
47 116
        return $this->getUniqueString($this->getCleanName(), $additionalContext);
48
    }
49
50 112
    public function getGetterName(): string
51
    {
52 112
        return $this->replaceReservedMethod(sprintf('get%s', ucfirst($this->getUniqueName('get'))), $this->getOwner()->getPackagedName());
53
    }
54
55 112
    public function getSetterName(): string
56
    {
57 112
        return $this->replaceReservedMethod(sprintf('set%s', ucfirst($this->getUniqueName('set'))), $this->getOwner()->getPackagedName());
58
    }
59
60 156
    public function getType(bool $useTypeStruct = false): string
61
    {
62 156
        if ($useTypeStruct) {
63 2
            $typeStruct = $this->getTypeStruct();
64 2
            if ($typeStruct instanceof Struct) {
65 2
                $type = $typeStruct->getTopInheritance();
66
67 2
                return $type ?: $this->type;
68
            }
69
        }
70
71 156
        return $this->type;
72
    }
73
74 398
    public function setType(string $type): StructAttribute
75
    {
76 398
        $this->type = $type;
77
78 398
        return $this;
79
    }
80
81 6
    public function getContainsElements(): bool
82
    {
83 6
        return $this->containsElements;
84
    }
85
86
    /**
87
     * If already able to contain several occurrences, it must stay as it is, the wider behaviour wins.
88
     */
89 244
    public function setContainsElements(bool $containsElements = true): StructAttribute
90
    {
91 244
        $this->containsElements = $this->containsElements || $containsElements;
92
93 244
        return $this;
94
    }
95
96 116
    public function getRemovableFromRequest(): bool
97
    {
98 116
        return $this->removableFromRequest;
99
    }
100
101 110
    public function isAChoice(): bool
102
    {
103 110
        return is_array($this->getMetaValue('choice'));
104
    }
105
106
    /**
107
     * If already able to be removed from request, it must stay as it is, the wider behaviour wins.
108
     */
109 236
    public function setRemovableFromRequest(bool $removableFromRequest = true): StructAttribute
110
    {
111 236
        $this->removableFromRequest = $this->removableFromRequest || $removableFromRequest;
112
113 236
        return $this;
114
    }
115
116
    /**
117
     * If this attribute contains elements then it's an array
118
     * only if its parent, the Struct, is not itself an array,
119
     * if the parent is an array, then it is certainly an array too.
120
     */
121 122
    public function isArray(): bool
122
    {
123 122
        return $this->containsElements || $this->isTypeStructArray();
124
    }
125
126
    /**
127
     * If this attribute is based on a struct that is a list,
128
     * then it is a list of basic scalar values that are sent space-separated.
129
     */
130 122
    public function isList(): bool
131
    {
132 122
        $typeStruct = $this->getTypeStruct();
133
134 122
        return $typeStruct && $typeStruct->isList();
135
    }
136
137
    /**
138
     * @return null|array|bool|float|int|string
139
     */
140 112
    public function getDefaultValue(?string $type = null)
141
    {
142 112
        if (($struct = $this->getTypeStruct()) && $struct->isStruct()) {
143 82
            return null;
144
        }
145
146 98
        return Utils::getValueWithinItsType($this->getMetaValueFirstSet([
147 98
            'default',
148 98
            'Default',
149 98
            'DefaultValue',
150 98
            'defaultValue',
151 98
            'defaultvalue',
152 98
        ]), $type);
153
    }
154
155 112
    public function isRequired(): bool
156
    {
157 112
        return 'required' === $this->getMetaValue('use', '') || 0 < $this->getMetaValueFirstSet([
158 112
            'minOccurs',
159 112
            'minoccurs',
160 112
            'MinOccurs',
161 112
            'Minoccurs',
162 112
        ], 0);
163
    }
164
165 114
    public function isNullable(): bool
166
    {
167 114
        return 'true' === $this->getMetaValue('nillable', 'false');
168
    }
169
170 164
    public function getOwner(): Struct
171
    {
172 164
        return parent::getOwner();
0 ignored issues
show
Bug Best Practice introduced by
The expression return parent::getOwner() returns the type null which is incompatible with the type-hinted return WsdlToPhp\PackageGenerator\Model\Struct.
Loading history...
173
    }
174
175 122
    public function isXml(): bool
176
    {
177 122
        return \DOMDocument::class === $this->getType();
178
    }
179
180 150
    public function getTypeStruct(): ?Struct
181
    {
182 150
        $struct = $this->getGenerator()->getStructByNameAndType($this->getType(), $this->getInheritance());
183
184 150
        return $struct ?: $this->getGenerator()->getStructByName($this->getType());
185
    }
186
187 150
    public function getTypeStructMeta(): array
188
    {
189 150
        $typeStruct = $this->getTypeStruct();
190
191 150
        return ($typeStruct && !$typeStruct->isStruct()) ? $typeStruct->getMeta() : [];
192
    }
193
194 98
    public function isTypeStructArray(): bool
195
    {
196 98
        $typeStruct = $this->getTypeStruct();
197
198 98
        return $typeStruct && $typeStruct->isArray() && !$typeStruct->isStruct();
199
    }
200
201 150
    public function getInheritanceStruct(): ?Struct
202
    {
203 150
        return $this->getGenerator()->getStructByName($this->getInheritance());
204
    }
205
206 150
    public function getInheritanceStructMeta(): array
207
    {
208 150
        $inheritanceStruct = $this->getInheritanceStruct();
209
210 150
        return ($inheritanceStruct && !$inheritanceStruct->isStruct()) ? $inheritanceStruct->getMeta() : [];
211
    }
212
213 150
    public function getMeta(): array
214
    {
215 150
        return $this->mergeMeta($this->getInheritanceStructMeta(), $this->getTypeStructMeta(), parent::getMeta());
216
    }
217
218 114
    public function getReservedMethodsInstance(?string $filename = null): AbstractReservedWord
219
    {
220 114
        return $this->getOwner()->getReservedMethodsInstance($filename);
221
    }
222
223 2
    protected function toJsonSerialize(): array
224
    {
225 2
        return [
226 2
            'containsElements' => $this->containsElements,
227 2
            'removableFromRequest' => $this->removableFromRequest,
228 2
            'type' => $this->type,
229 2
        ];
230
    }
231
}
232