Completed
Push — develop ( adf0de...0b548c )
by Mikaël
33:13
created

addStructMethodsGetAnnotationBlockFromXmlAttribute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

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