Completed
Push — master ( 06621f...b41c10 )
by Mikaël
30:47
created

Struct::getStructMethodParameter()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 5.024

Importance

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