Completed
Push — feature/issue-128 ( 76ec1f...542503 )
by Mikaël
23:56
created

Struct::addStructMethodSetBody()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

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