Completed
Push — master ( 060bfa...009823 )
by Mikaël
50:16 queued 31:14
created

Struct   F

Complexity

Total Complexity 96

Size/Duplication

Total Lines 604
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Test Coverage

Coverage 97.41%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 96
lcom 1
cbo 14
dl 0
loc 604
ccs 301
cts 309
cp 0.9741
rs 2.6573
c 1
b 0
f 0

43 Methods

Rating   Name   Duplication   Size   Complexity  
A getClassConstants() 0 3 1
A getConstantAnnotationBlock() 0 3 1
A getModelAttributes() 0 4 1
A getClassProperties() 0 8 3
A getPropertyAnnotationBlock() 0 14 3
A getClassMethods() 0 4 1
A addStructMethodConstruct() 0 7 1
A addStructMethodConstructBody() 0 11 3
A addStructMethodConstructBodyForAttribute() 0 5 2
A getStructMethodParametersValues() 0 8 2
A getStructMethodParameter() 0 8 4
A getStructMethodParameterType() 0 4 1
A addStructMethodsSetAndGet() 0 7 2
A addStructMethodAddTo() 0 11 2
A addStructMethodSetBodyReturn() 0 5 1
A addStructMethodSetBodyForRestriction() 0 8 3
A getStructMethodSetBodyAssignment() 0 9 2
A getStructMethodGetParameters() 0 8 2
A addStructMethodSetState() 0 9 1
A getMethodAnnotationBlock() 0 4 1
B getStructMethodAnnotationBlock() 0 20 6
A getStructMethodConstructAnnotationBlock() 0 8 1
A getStructMethodSetStateAnnotationBlock() 0 11 1
C getStructMethodsSetAndGetAnnotationBlock() 0 35 8
A addStructMethodAddToBody() 0 9 2
A addStructMethodSet() 0 9 1
A addStructMethodSetBody() 0 8 2
A addStructMethodSetBodyAssignment() 0 14 3
A addStructMethodGetBody() 0 4 1
A addStructMethodGetBodyForXml() 0 14 2
A addStructMethodGetBodyReturn() 0 15 4
A addStructMethodGet() 0 12 2
C addStructMethodsSetAndGetAnnotationBlockFromStructAttribute() 0 26 7
A addStructMethodsSetAndGetAnnotationBlockFromScalar() 0 12 3
A addStructMethodsSetAnnotationBlock() 0 5 1
A addStructMethodsGetAnnotationBlock() 0 5 1
A addStructMethodsGetAnnotationBlockFromXmlAttribute() 0 13 2
A addStructPropertiesToAnnotationBlock() 0 4 1
A addStructPropertiesToAnnotationBlockUses() 0 7 2
A addStructPropertiesToAnnotationBlockParams() 0 7 2
A getStructMethodsAddToAnnotationBlock() 0 18 4
A getModel() 0 4 1
A setModel() 0 7 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\File;
4
5
use WsdlToPhp\PackageGenerator\Model\AbstractModel;
6
use WsdlToPhp\PackageGenerator\Model\StructAttribute as StructAttributeModel;
7
use WsdlToPhp\PackageGenerator\Model\Struct as StructModel;
8
use WsdlToPhp\PackageGenerator\Container\PhpElement\Method as MethodContainer;
9
use WsdlToPhp\PackageGenerator\Container\PhpElement\Property as PropertyContainer;
10
use WsdlToPhp\PackageGenerator\Container\PhpElement\Constant as ConstantContainer;
11
use WsdlToPhp\PackageGenerator\Container\Model\StructAttribute as StructAttributeContainer;
12
use WsdlToPhp\PhpGenerator\Element\PhpAnnotation;
13
use WsdlToPhp\PhpGenerator\Element\PhpAnnotationBlock;
14
use WsdlToPhp\PhpGenerator\Element\PhpMethod;
15
use WsdlToPhp\PhpGenerator\Element\PhpProperty;
16
use WsdlToPhp\PhpGenerator\Element\PhpConstant;
17
use WsdlToPhp\PhpGenerator\Element\PhpFunctionParameter;
18
use WsdlToPhp\PackageGenerator\File\Validation\Rules;
19
20
class Struct extends AbstractModelFile
21
{
22
    /**
23
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getClassConstants()
24
     */
25 155
    protected function getClassConstants(ConstantContainer $constants)
26
    {
27 155
    }
28
    /**
29
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getConstantAnnotationBlock()
30
     */
31
    protected function getConstantAnnotationBlock(PhpConstant $constant)
32
    {
33
    }
34
    /**
35
     * @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.
36
     * @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
37
     * @return StructAttributeContainer
38
     */
39 155
    protected function getModelAttributes($includeInheritanceAttributes = false, $requiredFirst = true)
40
    {
41 155
        return $this->getModel()->getAttributes($includeInheritanceAttributes, $requiredFirst);
42
    }
43
    /**
44
     * @param PropertyContainer $properties
45
     */
46 190
    protected function getClassProperties(PropertyContainer $properties)
47
    {
48 190
        if ($this->getModel()->getAttributes()->count() > 0) {
49 155
            foreach ($this->getModelAttributes() as $attribute) {
50 155
                $properties->add(new PhpProperty($attribute->getCleanName(), PhpProperty::NO_VALUE));
51 93
            }
52 93
        }
53 190
    }
54
    /**
55
     * @return PhpAnnotationBlock $property
56
     */
57 155
    protected function getPropertyAnnotationBlock(PhpProperty $property)
58
    {
59 155
        $annotationBlock = new PhpAnnotationBlock();
60 155
        $annotationBlock->addChild(sprintf('The %s', $property->getName()));
61 155
        $attribute = $this->getModel()->getAttribute($property->getName());
62 155
        if (!$attribute instanceof StructAttributeModel) {
63 5
            $attribute = $this->getModel()->getAttributeByCleanName($property->getName());
64 3
        }
65 155
        if ($attribute instanceof StructAttributeModel) {
66 155
            $this->defineModelAnnotationsFromWsdl($annotationBlock, $attribute);
67 155
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_VAR, $this->getStructAttributeTypeSetAnnotation($attribute, true)));
68 93
        }
69 155
        return $annotationBlock;
70
    }
71
    /**
72
     * @param MethodContainer $methods
73
     */
74 155
    protected function getClassMethods(MethodContainer $methods)
75
    {
76 155
        $this->addStructMethodConstruct($methods)->addStructMethodsSetAndGet($methods)->addStructMethodSetState($methods);
77 155
    }
78
    /**
79
     * @param MethodContainer $methods
80
     * @return Struct
81
     */
82 155
    protected function addStructMethodConstruct(MethodContainer $methods)
83
    {
84 155
        $method = new PhpMethod(self::METHOD_CONSTRUCT, $this->getStructMethodParametersValues());
85 155
        $this->addStructMethodConstructBody($method);
86 155
        $methods->add($method);
87 155
        return $this;
88
    }
89
    /**
90
     * @param PhpMethod $method
91
     * @return Struct
92
     */
93 155
    protected function addStructMethodConstructBody(PhpMethod $method)
94
    {
95 155
        $count = $this->getModelAttributes()->count();
96 155
        foreach ($this->getModelAttributes() as $index => $attribute) {
97 155
            if ($index === 0) {
98 155
                $method->addChild('$this');
99 93
            }
100 155
            $this->addStructMethodConstructBodyForAttribute($method, $attribute, $count - 1 === $index);
101 93
        }
102 155
        return $this;
103
    }
104
    /**
105
     * @param PhpMethod $method
106
     * @param StructAttributeModel $attribute
107
     * @param bool $isLast
108
     * @return Struct
109
     */
110 155
    protected function addStructMethodConstructBodyForAttribute(PhpMethod $method, StructAttributeModel $attribute, $isLast)
111
    {
112 155
        $method->addChild($method->getIndentedString(sprintf('->%s($%s)%s', $attribute->getSetterName(), lcfirst($attribute->getCleanName()), $isLast ? ';' : ''), 1));
113 155
        return $this;
114
    }
115
    /**
116
     * @return PhpFunctionParameter[]
117
     */
118 155
    protected function getStructMethodParametersValues()
119
    {
120 155
        $parametersValues = array();
121 155
        foreach ($this->getModelAttributes() as $attribute) {
122 155
            $parametersValues[] = $this->getStructMethodParameter($attribute, true);
123 93
        }
124 155
        return $parametersValues;
125
    }
126
    /**
127
     * @param StructAttributeModel $attribute
128
     * @param bool $lowCaseFirstLetter
129
     * @param mixed $defaultValue
130
     * @return PhpFunctionParameter
131
     */
132 155
    protected function getStructMethodParameter(StructAttributeModel $attribute, $lowCaseFirstLetter = false, $defaultValue = null)
133
    {
134
        try {
135 155
            return new PhpFunctionParameter($lowCaseFirstLetter ? lcfirst($attribute->getCleanName()) : $attribute->getCleanName(), isset($defaultValue) ? $defaultValue : $attribute->getDefaultValue(), $this->getStructMethodParameterType($attribute));
136
        } catch (\InvalidArgumentException $exception) {
137
            throw new \InvalidArgumentException(sprintf('Unable to create function parameter for struct "%s" with type "%s" for attribute "%s"', $this->getModel()->getName(), var_export($this->getStructMethodParameterType($attribute), true), $attribute->getName()), __LINE__, $exception);
138
        }
139
    }
140
    /**
141
     * @param StructAttributeModel $attribute
142
     * @param bool $returnArrayType
143
     * @return string|null
144
     */
145 155
    protected function getStructMethodParameterType(StructAttributeModel $attribute, $returnArrayType = true)
146
    {
147 155
        return self::getValidType($this->getStructAttributeTypeHint($attribute, $returnArrayType), null);
148
    }
149
    /**
150
     * @param MethodContainer $methods
151
     * @return Struct
152
     */
153 155
    protected function addStructMethodsSetAndGet(MethodContainer $methods)
154
    {
155 155
        foreach ($this->getModelAttributes() as $attribute) {
156 155
            $this->addStructMethodGet($methods, $attribute)->addStructMethodSet($methods, $attribute)->addStructMethodAddTo($methods, $attribute);
157 93
        }
158 155
        return $this;
159
    }
160
    /**
161
     * @param MethodContainer $methods
162
     * @param StructAttributeModel $attribute
163
     * @return Struct
164
     */
165 155
    protected function addStructMethodAddTo(MethodContainer $methods, StructAttributeModel $attribute)
166
    {
167 155
        if ($attribute->isArray()) {
168 95
            $method = new PhpMethod(sprintf('addTo%s', ucfirst($attribute->getCleanName())), array(
169 95
                new PhpFunctionParameter('item', PhpFunctionParameter::NO_VALUE, $this->getStructMethodParameterType($attribute, false)),
170 57
            ));
171 95
            $this->addStructMethodAddToBody($method, $attribute);
172 95
            $methods->add($method);
173 57
        }
174 155
        return $this;
175
    }
176
    /**
177
     * @param PhpMethod $method
178
     * @param StructAttributeModel $attribute
179
     * @return Struct
180
     */
181 95
    protected function addStructMethodAddToBody(PhpMethod $method, StructAttributeModel $attribute)
182
    {
183 95
        if ($this->getGenerator()->getOptionValidation()) {
184 95
            $rules = new Rules($this, $method, $attribute);
185 95
            $rules->applyRules('item', true);
186 57
        }
187 95
        $method->addChild(sprintf('$this->%s[] = $item;', $attribute->getCleanName()))->addChild('return $this;');
188 95
        return $this;
189
    }
190
    /**
191
     * @param MethodContainer $methods
192
     * @param StructAttributeModel $attribute
193
     * @return Struct
194
     */
195 155
    protected function addStructMethodSet(MethodContainer $methods, StructAttributeModel $attribute)
196
    {
197 155
        $method = new PhpMethod($attribute->getSetterName(), array(
198 155
            $this->getStructMethodParameter($attribute, true, null),
199 93
        ));
200 155
        $this->addStructMethodSetBody($method, $attribute);
201 155
        $methods->add($method);
202 155
        return $this;
203
    }
204
    /**
205
     * @param PhpMethod $method
206
     * @param StructAttributeModel $attribute
207
     * @return Struct
208
     */
209 155
    protected function addStructMethodSetBody(PhpMethod $method, StructAttributeModel $attribute)
210
    {
211 155
        if ($this->getGenerator()->getOptionValidation()) {
212 150
            $rules = new Rules($this, $method, $attribute);
213 150
            $rules->applyRules(lcfirst($attribute->getCleanName()));
214 90
        }
215 155
        return $this->addStructMethodSetBodyAssignment($method, $attribute)->addStructMethodSetBodyReturn($method);
216
    }
217
    /**
218
     * @param PhpMethod $method
219
     * @param StructAttributeModel $attribute
220
     * @return Struct
221
     */
222 155
    protected function addStructMethodSetBodyAssignment(PhpMethod $method, StructAttributeModel $attribute)
223
    {
224 155
        $parameterName = lcfirst($attribute->getCleanName());
225 155
        if ($attribute->getRemovableFromRequest()) {
226 25
            $method->addChild(sprintf('if (is_null($%1$s) || (is_array($%1$s) && empty($%1$s))) {', $parameterName))
227 25
                ->addChild($method->getIndentedString(sprintf('unset($this->%1$s%2$s);', $attribute->getCleanName(), $attribute->nameIsClean() ? '' : sprintf(', $this->{\'%s\'}', addslashes($attribute->getName()))), 1))
228 25
                ->addChild('} else {')
229 25
                ->addChild($method->getIndentedString($this->getStructMethodSetBodyAssignment($attribute, $parameterName), 1))
230 25
                ->addChild('}');
231 15
        } else {
232 150
            $method->addChild($this->getStructMethodSetBodyAssignment($attribute, $parameterName));
233
        }
234 155
        return $this;
235
    }
236
    /**
237
     * @param PhpMethod $method
238
     * @return Struct
239
     */
240 155
    protected function addStructMethodSetBodyReturn(PhpMethod $method)
241
    {
242 155
        $method->addChild('return $this;');
243 155
        return $this;
244
    }
245
    /**
246
     * @param PhpMethod $method
247
     * @param StructAttributeModel $attribute
248
     * @param string $parameterName
249
     * @return Struct
250
     */
251 20
    protected function addStructMethodSetBodyForRestriction(PhpMethod $method, StructAttributeModel $attribute, $parameterName = null)
252
    {
253 20
        if (($model = $this->getRestrictionFromStructAttribute($attribute)) instanceof StructModel) {
254 20
            $parameterName = empty($parameterName) ? lcfirst($attribute->getCleanName()) : $parameterName;
255 20
            $method->addChild(sprintf('if (!%s::%s($%s)) {', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID, $parameterName))->addChild($method->getIndentedString(sprintf('throw new \InvalidArgumentException(sprintf(\'Value "%%s" is invalid, please use one of: %%s\', $%s, implode(\', \', %s::%s())), __LINE__);', $parameterName, $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES), 1))->addChild('}');
256 12
        }
257 20
        return $this;
258
    }
259
    /**
260
     * @param StructAttributeModel $attribute
261
     * @param string $parameterName
262
     * @return string
263
     */
264 155
    protected function getStructMethodSetBodyAssignment(StructAttributeModel $attribute, $parameterName)
265
    {
266 155
        if ($attribute->nameIsClean()) {
267 155
            $assignment = sprintf('$this->%s = $%s;', $attribute->getName(), $parameterName);
268 93
        } else {
269 5
            $assignment = sprintf('$this->%s = $this->{\'%s\'} = $%s;', $attribute->getCleanName(), addslashes($attribute->getName()), $parameterName);
270
        }
271 155
        return $assignment;
272
    }
273
    /**
274
     * @param PhpMethod $method
275
     * @param StructAttributeModel $attribute
276
     * @param string $thisAccess
277
     * @return Struct
278
     */
279 155
    protected function addStructMethodGetBody(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
280
    {
281 155
        return $this->addStructMethodGetBodyForXml($method, $attribute, $thisAccess)->addStructMethodGetBodyReturn($method, $attribute, $thisAccess);
282
    }
283
    /**
284
     * @param PhpMethod $method
285
     * @param StructAttributeModel $attribute
286
     * @param string $thisAccess
287
     * @return Struct
288
     */
289 155
    protected function addStructMethodGetBodyForXml(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
290
    {
291 155
        if ($attribute->isXml()) {
292 5
            $method->addChild(sprintf('if (!empty($this->%1$s) && !($this->%1$s instanceof \DOMDocument)) {', $thisAccess))
293 5
                ->addChild($method->getIndentedString('$dom = new \DOMDocument(\'1.0\', \'UTF-8\');', 1))
294 5
                ->addChild($method->getIndentedString('$dom->formatOutput = true;', 1))
295 5
                ->addChild($method->getIndentedString(sprintf('if ($dom->loadXML($this->%s)) {', $thisAccess), 1))
296 5
                ->addChild($method->getIndentedString(sprintf('$this->%s($dom);', $attribute->getSetterName()), 2))
297 5
                ->addChild($method->getIndentedString('}', 1))
298 5
                ->addChild($method->getIndentedString('unset($dom);', 1))
299 5
                ->addChild('}');
300 3
        }
301 155
        return $this;
302
    }
303
    /**
304
     * @param PhpMethod $method
305
     * @param StructAttributeModel $attribute
306
     * @param string $thisAccess
307
     * @return Struct
308
     */
309 155
    protected function addStructMethodGetBodyReturn(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
310
    {
311 155
        $return = sprintf('return $this->%s;', $thisAccess);
312 155
        if ($attribute->isXml()) {
313 5
            if ($attribute->getRemovableFromRequest()) {
314
                $return = sprintf('return ($asString && isset($this->%1$s) && ($this->%1$s instanceof \DOMDocument) && $this->%1$s->hasChildNodes()) ? $this->%1$s->saveXML($this->%1$s->childNodes->item(0)) : (isset($this->%1$s) ? $this->%1$s : null);', $thisAccess);
315
            } else {
316 5
                $return = sprintf('return ($asString && ($this->%1$s instanceof \DOMDocument) && $this->%1$s->hasChildNodes()) ? $this->%1$s->saveXML($this->%1$s->childNodes->item(0)) : $this->%1$s;', $thisAccess);
317
            }
318 155
        } elseif ($attribute->getRemovableFromRequest()) {
319 25
            $return = sprintf('return isset($this->%1$s) ? $this->%1$s : null;', $thisAccess);
320 15
        }
321 155
        $method->addChild($return);
322 155
        return $this;
323
    }
324
    /**
325
     * @param MethodContainer $methods
326
     * @param StructAttributeModel $attribute
327
     * @return Struct
328
     */
329 155
    protected function addStructMethodGet(MethodContainer $methods, StructAttributeModel $attribute)
330
    {
331 155
        $method = new PhpMethod($attribute->getGetterName(), $this->getStructMethodGetParameters($attribute));
332 155
        if ($attribute->nameIsClean()) {
333 155
            $thisAccess = sprintf('%s', $attribute->getName());
334 93
        } else {
335 5
            $thisAccess = sprintf('{\'%s\'}', addslashes($attribute->getName()));
336
        }
337 155
        $this->addStructMethodGetBody($method, $attribute, $thisAccess);
338 155
        $methods->add($method);
339 155
        return $this;
340
    }
341
    /**
342
     * @param StructAttributeModel $attribute
343
     * @return PhpFunctionParameter[]
344
     */
345 155
    protected function getStructMethodGetParameters(StructAttributeModel $attribute)
346
    {
347 155
        $parameters = array();
348 155
        if ($attribute->isXml()) {
349 5
            $parameters[] = new PhpFunctionParameter('asString', true);
350 3
        }
351 155
        return $parameters;
352
    }
353
    /**
354
     * @param MethodContainer $methods
355
     * @return Struct
356
     */
357 155
    protected function addStructMethodSetState(MethodContainer $methods)
358
    {
359 155
        $method = new PhpMethod(self::METHOD_SET_STATE, array(
360 155
            new PhpFunctionParameter('array', PhpFunctionParameter::NO_VALUE, 'array'),
361 155
        ), PhpMethod::ACCESS_PUBLIC, false, true);
362 155
        $method->addChild(sprintf('return parent::__set_state($array);'));
363 155
        $methods->add($method);
364 155
        return $this;
365
    }
366
    /**
367
     * @return PhpAnnotationBlock|null
368
     */
369 155
    protected function getMethodAnnotationBlock(PhpMethod $method)
370
    {
371 155
        return $this->getStructMethodAnnotationBlock($method);
372
    }
373
    /**
374
     * @param PhpMethod $method
375
     * @return PhpAnnotationBlock|null
376
     */
377 155
    protected function getStructMethodAnnotationBlock(PhpMethod $method)
378
    {
379 155
        $annotationBlock = null;
380 155
        switch ($method->getName()) {
381 155
            case self::METHOD_CONSTRUCT:
382 155
                $annotationBlock = $this->getStructMethodConstructAnnotationBlock();
383 155
                break;
384 155
            case self::METHOD_SET_STATE:
385 155
                $annotationBlock = $this->getStructMethodSetStateAnnotationBlock();
386 155
                break;
387 155
            case strpos($method->getName(), 'get') === 0:
388 155
            case strpos($method->getName(), 'set') === 0:
389 155
                $annotationBlock = $this->getStructMethodsSetAndGetAnnotationBlock($method);
390 155
                break;
391 95
            case strpos($method->getName(), 'addTo') === 0:
392 95
                $annotationBlock = $this->getStructMethodsAddToAnnotationBlock($method);
393 95
                break;
394 93
        }
395 155
        return $annotationBlock;
396
    }
397
    /**
398
     * @return PhpAnnotationBlock
399
     */
400 155
    protected function getStructMethodConstructAnnotationBlock()
401
    {
402 155
        $annotationBlock = new PhpAnnotationBlock(array(
403 155
            sprintf('Constructor method for %s', $this->getModel()->getName()),
404 93
        ));
405 155
        $this->addStructPropertiesToAnnotationBlock($annotationBlock);
406 155
        return $annotationBlock;
407
    }
408
    /**
409
     * @return PhpAnnotationBlock
410
     */
411 155
    protected function getStructMethodSetStateAnnotationBlock()
412
    {
413 155
        return new PhpAnnotationBlock(array(
414 155
            'Method called when an object has been exported with var_export() functions',
415 155
            'It allows to return an object instantiated with the values',
416 155
            new PhpAnnotation(self::ANNOTATION_SEE, sprintf('%s::__set_state()', $this->getModel()->getExtends(true))),
417 155
            new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::__set_state()', $this->getModel()->getExtends(true))),
418 155
            new PhpAnnotation(self::ANNOTATION_PARAM, 'array $array the exported values'),
419 155
            new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)),
420 93
        ));
421
    }
422
    /**
423
     * @param PhpMethod $method
424
     * @return PhpAnnotationBlock
425
     */
426 155
    protected function getStructMethodsSetAndGetAnnotationBlock(PhpMethod $method)
427
    {
428 155
        $parameters = $method->getParameters();
429 155
        $setOrGet = strtolower(substr($method->getName(), 0, 3));
430 155
        $parameter = array_shift($parameters);
431
        /**
432
         * Only set parameter must be based on a potential PhpFunctionParameter
433
         */
434 155
        if ($parameter instanceof PhpFunctionParameter && $setOrGet === 'set') {
435 155
            $parameterName = ucfirst($parameter->getName());
436 93
        } else {
437 155
            $parameterName = substr($method->getName(), 3);
438
        }
439 155
        $attribute = $this->getModel()->getAttribute($parameterName);
440 155
        if (!$attribute instanceof StructAttributeModel) {
441 75
            $attribute = $this->getModel()->getAttributeByCleanName($parameterName);
442 45
        }
443 155
        if (!$attribute instanceof StructAttributeModel) {
444 75
            $parameterName = lcfirst($parameterName);
445 75
            $attribute = $this->getModel()->getAttribute($parameterName);
446 75
            if (!$attribute instanceof StructAttributeModel) {
447 10
                $attribute = $this->getModel()->getAttributeByCleanName($parameterName);
448 6
            }
449 45
        }
450 155
        $setValueAnnotation = '%s %s value';
451 155
        $annotationBlock = new PhpAnnotationBlock();
452 155
        if ($attribute instanceof StructAttributeModel) {
453 155
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), $parameterName));
454 155
            $this->addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, $annotationBlock, $attribute);
455 93
        } elseif (empty($attribute)) {
456 5
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), lcfirst($parameterName)));
457 5
            $this->addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, $annotationBlock, $parameterName);
458 3
        }
459 155
        return $annotationBlock;
460
    }
461
    /**
462
     * @param string $setOrGet
463
     * @param PhpAnnotationBlock $annotationBlock
464
     * @param StructAttributeModel $attribute
465
     * @return Struct
466
     */
467 155
    protected function addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
468
    {
469
        switch ($setOrGet) {
470 155
            case 'set':
471 155
                if ($attribute->getRemovableFromRequest()) {
472 25
                    $annotationBlock->addChild('This property is removable from request (nillable=true+minOccurs=0), therefore if the value assigned to this property is null, it is removed from this object');
473 15
                }
474 155
                if (($model = $this->getRestrictionFromStructAttribute($attribute)) instanceof StructModel) {
475
                    $annotationBlock
476 85
                        ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID)))
477 85
                        ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES)))
478 85
                        ->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
479 153
                } elseif ($attribute->isArray()) {
480 90
                    $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
481 54
                }
482 155
                $this->addStructMethodsSetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()));
483 155
                break;
484 155
            case 'get':
485 155
                if ($attribute->getRemovableFromRequest()) {
486 25
                    $annotationBlock->addChild('An additional test has been added (isset) before returning the property value as this property may have been unset before, due to the fact that this property is removable from the request (nillable=true+minOccurs=0)');
487 15
                }
488 155
                $this->addStructMethodsGetAnnotationBlockFromXmlAttribute($annotationBlock, $attribute)->addStructMethodsGetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeGetAnnotation($attribute));
489 155
                break;
490
        }
491 155
        return $this;
492
    }
493
    /**
494
     * @param string $setOrGet
495
     * @param PhpAnnotationBlock $annotationBlock
496
     * @param string $attributeName
497
     * @return Struct
498
     */
499 5
    protected function addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, PhpAnnotationBlock $annotationBlock, $attributeName)
500
    {
501
        switch ($setOrGet) {
502 5
            case 'set':
503
                $this->addStructMethodsSetAnnotationBlock($annotationBlock, lcfirst($attributeName), lcfirst($attributeName));
504
                break;
505 5
            case 'get':
506 5
                $this->addStructMethodsGetAnnotationBlock($annotationBlock, lcfirst($attributeName));
507 5
                break;
508
        }
509 5
        return $this;
510
    }
511
    /**
512
     * @param PhpAnnotationBlock $annotationBlock
513
     * @param string $type
514
     * @param string $name
515
     * @return Struct
516
     */
517 155
    protected function addStructMethodsSetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $type, $name)
518
    {
519 155
        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $type, $name)))->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)));
520 155
        return $this;
521
    }
522
    /**
523
     * @param PhpAnnotationBlock $annotationBlock
524
     * @param string $attributeType
525
     * @return Struct
526
     */
527 155
    protected function addStructMethodsGetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $attributeType)
528
    {
529 155
        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $attributeType));
530 155
        return $this;
531
    }
532
    /**
533
     * @param PhpAnnotationBlock $annotationBlock
534
     * @param StructAttributeModel $attribute
535
     * @return Struct
536
     */
537 155
    protected function addStructMethodsGetAnnotationBlockFromXmlAttribute(PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
538
    {
539 155
        if ($attribute->isXml()) {
540 5
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::loadXML()'))
541 5
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::hasChildNodes()'))
542 5
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::saveXML()'))
543 5
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMNode::item()'))
544 5
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $this->getModel()
545 5
                ->getPackagedName(true), $attribute->getSetterName())))
546 5
                ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, 'bool $asString true: returns XML string, false: returns \DOMDocument'));
547 3
        }
548 155
        return $this;
549
    }
550
    /**
551
     * @param PhpAnnotationBlock $annotationBlock
552
     * @return Struct
553
     */
554 155
    protected function addStructPropertiesToAnnotationBlock(PhpAnnotationBlock $annotationBlock)
555
    {
556 155
        return $this->addStructPropertiesToAnnotationBlockUses($annotationBlock)->addStructPropertiesToAnnotationBlockParams($annotationBlock);
557
    }
558
    /**
559
     * @param PhpAnnotationBlock $annotationBlock
560
     * @return Struct
561
     */
562 155
    protected function addStructPropertiesToAnnotationBlockUses(PhpAnnotationBlock $annotationBlock)
563
    {
564 155
        foreach ($this->getModelAttributes() as $attribute) {
565 155
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $this->getModel()->getPackagedName(), $attribute->getSetterName())));
566 93
        }
567 155
        return $this;
568
    }
569
    /**
570
     * @param PhpAnnotationBlock $annotationBlock
571
     * @return Struct
572
     */
573 155
    protected function addStructPropertiesToAnnotationBlockParams(PhpAnnotationBlock $annotationBlock)
574
    {
575 155
        foreach ($this->getModelAttributes() as $attribute) {
576 155
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()))));
577 93
        }
578 155
        return $this;
579
    }
580
    /**
581
     * @param PhpMethod $method
582
     * @return PhpAnnotationBlock
583
     */
584 95
    protected function getStructMethodsAddToAnnotationBlock(PhpMethod $method)
585
    {
586 95
        $attributeName = str_replace('addTo', '', $method->getName());
587 95
        $attribute = $this->getModel()->getAttribute($attributeName);
588 95
        if (!$attribute instanceof StructAttributeModel) {
589 40
            $attribute = $this->getModel()->getAttribute(lcfirst($attributeName));
590 24
        }
591 95
        $model = $this->getRestrictionFromStructAttribute($attribute);
592 95
        $annotationBlock = new PhpAnnotationBlock();
593 95
        if ($attribute instanceof StructAttributeModel) {
594 95
            $annotationBlock->addChild(sprintf('Add item to %s value', $attribute->getCleanName()));
595 95
            if ($model instanceof StructModel) {
596 25
                $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID)))->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES)));
597 15
            }
598 95
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'))->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $item', $this->getStructAttributeTypeSetAnnotation($attribute, false))))->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)));
599 57
        }
600 95
        return $annotationBlock;
601
    }
602
    /**
603
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getModel()
604
     * @return StructModel
605
     */
606 255
    public function getModel()
607
    {
608 255
        return parent::getModel();
609
    }
610
    /**
611
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::setModel()
612
     * @throws \InvalidArgumentException
613
     * @param AbstractModel $model
614
     * @return StructArray
615
     */
616 215
    public function setModel(AbstractModel $model)
617
    {
618 215
        if (!$model instanceof StructModel) {
619 5
            throw new \InvalidArgumentException('Model must be an instance of a Struct', __LINE__);
620
        }
621 210
        return parent::setModel($model);
622
    }
623
}
624