Completed
Push — feature/issue-133 ( 6faf89...46a72f )
by Mikaël
23:25 queued 49s
created

Struct   F

Complexity

Total Complexity 98

Size/Duplication

Total Lines 615
Duplicated Lines 0 %

Test Coverage

Coverage 98.13%

Importance

Changes 0
Metric Value
eloc 243
dl 0
loc 615
ccs 314
cts 320
cp 0.9813
rs 2
c 0
b 0
f 0
wmc 98

43 Methods

Rating   Name   Duplication   Size   Complexity  
A getStructMethodParameter() 0 7 4
A getClassProperties() 0 5 3
A addStructMethodAddToBody() 0 8 2
A addStructMethodGet() 0 11 2
A addStructMethodGetBody() 0 3 1
A getStructMethodSetStateAnnotationBlock() 0 9 1
A addStructMethodSetBodyReturn() 0 4 1
A addStructMethodSetState() 0 8 1
A getModelAttributes() 0 3 1
A addStructMethodSet() 0 8 1
A getStructMethodParametersValues() 0 7 2
A addStructMethodConstructBodyForAttribute() 0 5 2
A addStructMethodGetBodyReturn() 0 14 4
A getStructMethodParameterType() 0 3 1
A addStructMethodSetBody() 0 8 2
A getStructMethodAnnotationBlock() 0 19 6
A getMethodAnnotationBlock() 0 3 1
A getStructMethodGetParameters() 0 7 2
A getConstantAnnotationBlock() 0 2 1
A getPropertyAnnotationBlock() 0 13 3
A getClassConstants() 0 2 1
A getStructMethodConstructAnnotationBlock() 0 7 1
A getStructMethodSetBodyAssignment() 0 8 2
A addStructMethodSetBodyForRestriction() 0 7 3
A addStructMethodSetBodyAssignment() 0 14 3
A addStructMethodAddTo() 0 10 2
A addStructMethodConstruct() 0 6 1
A addStructMethodGetBodyForXml() 0 13 2
A getClassMethods() 0 3 1
B getStructMethodsSetAndGetAnnotationBlock() 0 38 8
A addStructMethodConstructBody() 0 10 3
A addStructMethodsSetAndGet() 0 6 2
A addStructPropertiesToAnnotationBlockParams() 0 6 2
A getModel() 0 3 1
A addStructMethodsSetAndGetAnnotationBlockFromScalar() 0 11 3
A addStructPropertiesToAnnotationBlockUses() 0 6 2
A getStructMethodsAddToAnnotationBlock() 0 17 4
A addStructMethodsGetAnnotationBlockFromXmlAttribute() 0 12 2
B addStructMethodsSetAndGetAnnotationBlockFromStructAttribute() 0 30 9
A addStructPropertiesToAnnotationBlock() 0 3 1
A addStructMethodsGetAnnotationBlock() 0 4 1
A setModel() 0 6 2
A addStructMethodsSetAnnotationBlock() 0 4 1

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.

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