Completed
Push — feature/issue-82 ( aeff8b )
by Mikaël
02:06
created

Struct::addStructMethodGetBody()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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