Passed
Push — feature/issue-165 ( 2b7e50...101bca )
by Mikaël
14:10
created

Struct::getStructMethodAnnotationBlock()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 22
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 7

Importance

Changes 0
Metric Value
cc 7
eloc 19
nc 7
nop 1
dl 0
loc 22
ccs 15
cts 15
cp 1
crap 7
rs 8.8333
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\PackageGenerator\Model\StructAttribute;
13
use WsdlToPhp\PhpGenerator\Element\PhpAnnotation;
14
use WsdlToPhp\PhpGenerator\Element\PhpAnnotationBlock;
15
use WsdlToPhp\PhpGenerator\Element\PhpMethod;
16
use WsdlToPhp\PhpGenerator\Element\PhpProperty;
17
use WsdlToPhp\PhpGenerator\Element\PhpConstant;
18
use WsdlToPhp\PhpGenerator\Element\PhpFunctionParameter;
19
use WsdlToPhp\PackageGenerator\File\Validation\Rules;
20
21
class Struct extends AbstractModelFile
22
{
23
    /**
24
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getClassConstants()
25 198
     */
26
    protected function getClassConstants(ConstantContainer $constants)
27 198
    {
28
    }
29
    /**
30
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getConstantAnnotationBlock()
31
     */
32
    protected function getConstantAnnotationBlock(PhpConstant $constant)
33
    {
34
    }
35
    /**
36
     * @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.
37
     * @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
38
     * @return StructAttributeContainer
39 198
     */
40
    protected function getModelAttributes($includeInheritanceAttributes = false, $requiredFirst = true)
41 198
    {
42
        return $this->getModel()->getAttributes($includeInheritanceAttributes, $requiredFirst);
43
    }
44
    /**
45
     * @param PropertyContainer $properties
46 240
     */
47
    protected function getClassProperties(PropertyContainer $properties)
48 240
    {
49 198
        if ($this->getModel()->getAttributes()->count() > 0) {
50 198
            foreach ($this->getModelAttributes() as $attribute) {
51 99
                $properties->add(new PhpProperty($attribute->getCleanName(), PhpProperty::NO_VALUE));
52 99
            }
53 240
        }
54
    }
55
    /**
56
     * @return PhpAnnotationBlock $property
57 198
     */
58
    protected function getPropertyAnnotationBlock(PhpProperty $property)
59 198
    {
60 198
        $annotationBlock = new PhpAnnotationBlock();
61 198
        $annotationBlock->addChild(sprintf('The %s', $property->getName()));
62 198
        $attribute = $this->getModel()->getAttribute($property->getName());
63 6
        if (!$attribute instanceof StructAttributeModel) {
64 3
            $attribute = $this->getModel()->getAttributeByCleanName($property->getName());
65 198
        }
66 198
        if ($attribute instanceof StructAttributeModel) {
0 ignored issues
show
introduced by
$attribute is always a sub-type of WsdlToPhp\PackageGenerator\Model\StructAttribute.
Loading history...
67 198
            $this->defineModelAnnotationsFromWsdl($annotationBlock, $attribute);
68 99
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_VAR, $this->getStructAttributeTypeSetAnnotation($attribute, true)));
69 198
        }
70
        return $annotationBlock;
71
    }
72
    protected function fillClassMethods()
73
    {
74 198
        $this
75
            ->addStructMethodConstruct()
76 198
            ->addStructMethodsSetAndGet()
77 198
            ->addStructMethodSetState();
78
    }
79
    /**
80
     * @return Struct
81
     */
82 198
    protected function addStructMethodConstruct()
83
    {
84 198
        $method = new PhpMethod(self::METHOD_CONSTRUCT, $this->getStructMethodParametersValues());
85 198
        $this->addStructMethodConstructBody($method);
86 198
        $this->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
     * @return Struct
153
     */
154
    protected function addStructMethodsSetAndGet()
155 198
    {
156
        foreach ($this->getModelAttributes() as $attribute) {
157 198
            $this
158 198
                ->addStructMethodGet($attribute)
159 99
                ->addStructMethodSet($attribute)
160 198
                ->addStructMethodAddTo($attribute);
161
        }
162
        return $this;
163
    }
164
    /**
165
     * @param StructAttributeModel $attribute
166
     * @return Struct
167 198
     */
168
    protected function addStructMethodAddTo(StructAttributeModel $attribute)
169 198
    {
170 114
        if ($attribute->isArray()) {
171 114
            $method = new PhpMethod(sprintf('addTo%s', ucfirst($attribute->getCleanName())), [
172 57
                new PhpFunctionParameter('item', PhpFunctionParameter::NO_VALUE, $this->getStructMethodParameterType($attribute, false)),
173 114
            ]);
174 114
            $this->addStructMethodAddToBody($method, $attribute);
175 57
            $this->methods->add($method);
176 198
        }
177
        return $this;
178
    }
179
    /**
180
     * @param PhpMethod $method
181
     * @param StructAttributeModel $attribute
182
     * @return Struct
183 114
     */
184
    protected function addStructMethodAddToBody(PhpMethod $method, StructAttributeModel $attribute)
185 114
    {
186 114
        if ($this->getGenerator()->getOptionValidation()) {
187 114
            $this->applyRules($method, $attribute, 'item', true);
188 57
        }
189 114
        $method
190 114
            ->addChild(sprintf('$this->%s[] = $item;', $attribute->getCleanName()))
191
            ->addChild('return $this;');
192
        return $this;
193
    }
194
    /**
195
     * @param StructAttributeModel $attribute
196
     * @return Struct
197 198
     */
198
    protected function addStructMethodSet(StructAttributeModel $attribute)
199 198
    {
200 198
        $method = new PhpMethod($attribute->getSetterName(), [
201 99
            $this->getStructMethodParameter($attribute, true, null),
202 198
        ]);
203 198
        $this->addStructMethodSetBody($method, $attribute);
204 198
        $this->methods->add($method);
205
        return $this;
206
    }
207
    /**
208
     * @param PhpMethod $method
209
     * @param StructAttributeModel $attribute
210
     * @return Struct
211 198
     */
212
    protected function addStructMethodSetBody(PhpMethod $method, StructAttributeModel $attribute)
213 198
    {
214 192
        if ($this->getGenerator()->getOptionValidation()) {
215 192
            $uniqueString = $attribute->getUniqueString($attribute->getCleanName());
216 192
            $this->applyRules($method, $attribute, 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
231 30
                ->addChild(sprintf('if (is_null($%1$s) || (is_array($%1$s) && empty($%1$s))) {', $parameterName))
232 30
                ->addChild($method->getIndentedString(sprintf('unset($this->%1$s%2$s);', $attribute->getCleanName(), $attribute->nameIsClean() ? '' : sprintf(', $this->{\'%s\'}', addslashes($attribute->getName()))), 1))
233 30
                ->addChild('} else {')
234 30
                ->addChild($method->getIndentedString($this->getStructMethodSetBodyAssignment($attribute, $parameterName), 1))
235 15
                ->addChild('}');
236 192
        } else {
237
            $method->addChild($this->getStructMethodSetBodyAssignment($attribute, $parameterName));
238 198
        }
239
        return $this;
240
    }
241
    /**
242
     * @param PhpMethod $method
243
     * @return Struct
244 198
     */
245
    protected function addStructMethodSetBodyReturn(PhpMethod $method)
246 198
    {
247 198
        $method->addChild('return $this;');
248
        return $this;
249
    }
250
    /**
251
     * @param StructAttributeModel $attribute
252
     * @param string $parameterName
253
     * @return string
254
     */
255 24
    protected function getStructMethodSetBodyAssignment(StructAttributeModel $attribute, $parameterName)
256
    {
257 24
        $isList = $this->isAttributeAList($attribute);
258 24
        $prefix = '$';
259 24
        if ($isList) {
260 12
            $prefix = '';
261 24
            $parameterName = sprintf('is_array($%1$s) ? implode(\' \', $%1$s) : null', $parameterName);
262
        }
263
        if ($attribute->nameIsClean()) {
264
            $assignment = sprintf('$this->%s = %s%s;', $attribute->getName(), $prefix, $parameterName);
265
        } else {
266
            $assignment = sprintf('$this->%s = $this->{\'%s\'} = %s%s;', $attribute->getCleanName(), addslashes($attribute->getName()), $prefix, $parameterName);
267
        }
268 198
        return $assignment;
269
    }
270 198
    /**
271 198
     * @param PhpMethod $method
272 99
     * @param StructAttributeModel $attribute
273 6
     * @param string $thisAccess
274
     * @return Struct
275 198
     */
276
    protected function addStructMethodGetBody(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
277
    {
278
        return $this->addStructMethodGetBodyForXml($method, $attribute, $thisAccess)->addStructMethodGetBodyReturn($method, $attribute, $thisAccess);
279
    }
280
    /**
281
     * @param PhpMethod $method
282
     * @param StructAttributeModel $attribute
283 198
     * @param string $thisAccess
284
     * @return Struct
285 198
     */
286
    protected function addStructMethodGetBodyForXml(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
287
    {
288
        if ($attribute->isXml()) {
289
            $method
290
                ->addChild(sprintf('if (!empty($this->%1$s) && !($this->%1$s instanceof \DOMDocument)) {', $thisAccess))
291
                ->addChild($method->getIndentedString('$dom = new \DOMDocument(\'1.0\', \'UTF-8\');', 1))
292
                ->addChild($method->getIndentedString('$dom->formatOutput = true;', 1))
293 198
                ->addChild($method->getIndentedString(sprintf('if ($dom->loadXML($this->%s)) {', $thisAccess), 1))
294
                ->addChild($method->getIndentedString(sprintf('$this->%s($dom);', $attribute->getSetterName()), 2))
295 198
                ->addChild($method->getIndentedString('}', 1))
296 6
                ->addChild($method->getIndentedString('unset($dom);', 1))
297 6
                ->addChild('}');
298 6
        }
299 6
        return $this;
300 6
    }
301 6
    /**
302 6
     * @param PhpMethod $method
303 6
     * @param StructAttributeModel $attribute
304 3
     * @param string $thisAccess
305 198
     * @return Struct
306
     */
307
    protected function addStructMethodGetBodyReturn(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
308
    {
309
        $return = sprintf('return $this->%s;', $thisAccess);
310
        if ($attribute->isXml()) {
311
            if ($attribute->getRemovableFromRequest()) {
312
                $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);
313 198
            } else {
314
                $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);
315 198
            }
316 198
        } elseif ($attribute->getRemovableFromRequest()) {
317 6
            $return = sprintf('return isset($this->%1$s) ? $this->%1$s : null;', $thisAccess);
318
        }
319
        $method->addChild($return);
320 6
        return $this;
321
    }
322 198
    /**
323 30
     * @param StructAttributeModel $attribute
324 15
     * @return Struct
325 198
     */
326 198
    protected function addStructMethodGet(StructAttributeModel $attribute)
327
    {
328
        $method = new PhpMethod($attribute->getGetterName(), $this->getStructMethodGetParameters($attribute));
329
        if ($attribute->nameIsClean()) {
330
            $thisAccess = sprintf('%s', $attribute->getName());
331
        } else {
332
            $thisAccess = sprintf('{\'%s\'}', addslashes($attribute->getName()));
333 198
        }
334
        $this->addStructMethodGetBody($method, $attribute, $thisAccess);
335 198
        $this->methods->add($method);
336 198
        return $this;
337 198
    }
338 99
    /**
339 6
     * @param StructAttributeModel $attribute
340
     * @return PhpFunctionParameter[]
341 198
     */
342 198
    protected function getStructMethodGetParameters(StructAttributeModel $attribute)
343 198
    {
344
        $parameters = [];
345
        if ($attribute->isXml()) {
346
            $parameters[] = new PhpFunctionParameter('asString', true);
347
        }
348
        return $parameters;
349 198
    }
350
    /**
351 198
     * @return Struct
352 198
     */
353 6
    protected function addStructMethodSetState()
354 3
    {
355 198
        $method = new PhpMethod(self::METHOD_SET_STATE, [
356
            new PhpFunctionParameter('array', PhpFunctionParameter::NO_VALUE, 'array'),
357
        ], PhpMethod::ACCESS_PUBLIC, false, true);
358
        $method->addChild(sprintf('return parent::__set_state($array);'));
359
        $this->methods->add($method);
360
        return $this;
361 198
    }
362
    /**
363 198
     * @return PhpAnnotationBlock|null
364 198
     */
365 198
    protected function getMethodAnnotationBlock(PhpMethod $method)
366 198
    {
367 198
        return $this->getStructMethodAnnotationBlock($method);
368 198
    }
369
    /**
370
     * @param PhpMethod $method
371
     * @return PhpAnnotationBlock|null
372
     */
373 198
    protected function getStructMethodAnnotationBlock(PhpMethod $method)
374
    {
375 198
        $annotationBlock = null;
376
        switch ($method->getName()) {
377
            case self::METHOD_CONSTRUCT:
378
                $annotationBlock = $this->getStructMethodConstructAnnotationBlock();
379
                break;
380
            case self::METHOD_SET_STATE:
381 198
                $annotationBlock = $this->getStructMethodSetStateAnnotationBlock();
382
                break;
383 198
            case strpos($method->getName(), 'get') === 0:
384 198
            case strpos($method->getName(), 'set') === 0:
385 198
                $annotationBlock = $this->getStructMethodsSetAndGetAnnotationBlock($method);
386 198
                break;
387 198
            case strpos($method->getName(), 'addTo') === 0:
388 198
                $annotationBlock = $this->getStructMethodsAddToAnnotationBlock($method);
389 198
                break;
390 198
            case strpos($method->getName(), 'validate') === 0:
391 198
                $annotationBlock = $this->getStructMethodsValidateAnnotationBlock($method);
392 198
                break;
393 198
        }
394 198
        return $annotationBlock;
395 114
    }
396 114
    /**
397 114
     * @return PhpAnnotationBlock
398 99
     */
399 198
    protected function getStructMethodConstructAnnotationBlock()
400
    {
401
        $annotationBlock = new PhpAnnotationBlock([
402
            sprintf('Constructor method for %s', $this->getModel()->getName()),
403
        ]);
404 198
        $this->addStructPropertiesToAnnotationBlock($annotationBlock);
405
        return $annotationBlock;
406 198
    }
407 198
    /**
408 99
     * @return PhpAnnotationBlock
409 198
     */
410 198
    protected function getStructMethodSetStateAnnotationBlock()
411
    {
412
        return new PhpAnnotationBlock([
413
            'Method called when an object has been exported with var_export() functions',
414
            'It allows to return an object instantiated with the values',
415 198
            new PhpAnnotation(self::ANNOTATION_SEE, sprintf('%s::__set_state()', $this->getModel()->getExtends(true))),
416
            new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::__set_state()', $this->getModel()->getExtends(true))),
417 198
            new PhpAnnotation(self::ANNOTATION_PARAM, 'array $array the exported values'),
418 198
            new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)),
419 198
        ]);
420 198
    }
421 198
    /**
422 198
     * @param PhpMethod $method
423 198
     * @return PhpAnnotationBlock
424 99
     */
425
    protected function getStructMethodsSetAndGetAnnotationBlock(PhpMethod $method)
426
    {
427
        $parameters = $method->getParameters();
428
        $setOrGet = strtolower(substr($method->getName(), 0, 3));
429
        $parameter = array_shift($parameters);
430 198
        /**
431
         * Only set parameter must be based on a potential PhpFunctionParameter
432 198
         */
433 198
        if ($parameter instanceof PhpFunctionParameter && $setOrGet === 'set') {
434 198
            $parameterName = ucfirst($parameter->getName());
435
        } else {
436
            $parameterName = substr($method->getName(), 3);
437
        }
438 198
        /**
439 198
         * 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
440 99
         */
441 198
        $parameterName = preg_replace('/(_\d+)/', '', $parameterName);
442
        $attribute = $this->getModel()->getAttribute($parameterName);
443
        if (!$attribute instanceof StructAttributeModel) {
444
            $attribute = $this->getModel()->getAttributeByCleanName($parameterName);
445
        }
446 198
        if (!$attribute instanceof StructAttributeModel) {
0 ignored issues
show
introduced by
$attribute is always a sub-type of WsdlToPhp\PackageGenerator\Model\StructAttribute.
Loading history...
447 198
            $parameterName = lcfirst($parameterName);
448 198
            $attribute = $this->getModel()->getAttribute($parameterName);
449 90
            if (!$attribute instanceof StructAttributeModel) {
450 45
                $attribute = $this->getModel()->getAttributeByCleanName($parameterName);
451 198
            }
452 90
        }
453 90
        $setValueAnnotation = '%s %s value';
454 90
        $annotationBlock = new PhpAnnotationBlock();
455 12
        if ($attribute instanceof StructAttributeModel) {
0 ignored issues
show
introduced by
$attribute is always a sub-type of WsdlToPhp\PackageGenerator\Model\StructAttribute.
Loading history...
456 6
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), $parameterName));
457 45
            $this->addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, $annotationBlock, $attribute);
458 198
        } elseif (empty($attribute)) {
459 198
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), lcfirst($parameterName)));
460 198
            $this->addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, $annotationBlock, $parameterName);
461 198
        }
462 198
        return $annotationBlock;
463 99
    }
464 6
    /**
465 6
     * @param string $setOrGet
466 3
     * @param PhpAnnotationBlock $annotationBlock
467 198
     * @param StructAttributeModel $attribute
468
     * @return Struct
469
     */
470
    protected function addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
471
    {
472
        switch ($setOrGet) {
473
            case 'set':
474
                if ($attribute->getRemovableFromRequest()) {
475 198
                    $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');
476
                }
477 33
                if ($this->getGenerator()->getOptionValidation()) {
478 198
                    if (($model = $this->getRestrictionFromStructAttribute($attribute)) instanceof StructModel) {
479 198
                        $annotationBlock
480 30
                            ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID)))
481 15
                            ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES)))
482 198
                            ->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
483
                    } elseif ($attribute->isArray()) {
484 102
                        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
485 102
                    }
486 102
                }
487 195
                $this->addStructMethodsSetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()));
488 108
                break;
489 54
            case 'get':
490 198
                if ($attribute->getRemovableFromRequest()) {
491 198
                    $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 198
                }
493 198
                $this->addStructMethodsGetAnnotationBlockFromXmlAttribute($annotationBlock, $attribute)->addStructMethodsGetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeGetAnnotation($attribute));
494 30
                break;
495 15
        }
496 198
        return $this;
497 198
    }
498
    /**
499 198
     * @param string $setOrGet
500
     * @param PhpAnnotationBlock $annotationBlock
501
     * @param string $attributeName
502
     * @return Struct
503
     */
504
    protected function addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, PhpAnnotationBlock $annotationBlock, $attributeName)
505
    {
506
        switch ($setOrGet) {
507 6
            case 'set':
508
                $this->addStructMethodsSetAnnotationBlock($annotationBlock, lcfirst($attributeName), lcfirst($attributeName));
509 1
                break;
510 6
            case 'get':
511 6
                $this->addStructMethodsGetAnnotationBlock($annotationBlock, lcfirst($attributeName));
512 6
                break;
513 6
        }
514 6
        return $this;
515 6
    }
516
    /**
517 6
     * @param PhpAnnotationBlock $annotationBlock
518
     * @param string $type
519
     * @param string $name
520
     * @return Struct
521
     */
522
    protected function addStructMethodsSetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $type, $name)
523
    {
524
        $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 198
    /**
528 198
     * @param PhpAnnotationBlock $annotationBlock
529
     * @param string $attributeType
530
     * @return Struct
531
     */
532
    protected function addStructMethodsGetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $attributeType)
533
    {
534
        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $attributeType));
535 198
        return $this;
536
    }
537 198
    /**
538 198
     * @param PhpAnnotationBlock $annotationBlock
539
     * @param StructAttributeModel $attribute
540
     * @return Struct
541
     */
542
    protected function addStructMethodsGetAnnotationBlockFromXmlAttribute(PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
543
    {
544
        if ($attribute->isXml()) {
545 198
            $annotationBlock
546
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::loadXML()'))
547 198
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::hasChildNodes()'))
548 6
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::saveXML()'))
549 6
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMNode::item()'))
550 6
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $this->getModel()
551 6
                ->getPackagedName(true), $attribute->getSetterName())))
552 6
                ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, 'bool $asString true: returns XML string, false: returns \DOMDocument'));
553 6
        }
554 6
        return $this;
555 3
    }
556 198
    /**
557
     * @param PhpAnnotationBlock $annotationBlock
558
     * @return Struct
559
     */
560
    protected function addStructPropertiesToAnnotationBlock(PhpAnnotationBlock $annotationBlock)
561
    {
562 198
        return $this->addStructPropertiesToAnnotationBlockUses($annotationBlock)->addStructPropertiesToAnnotationBlockParams($annotationBlock);
563
    }
564 198
    /**
565
     * @param PhpAnnotationBlock $annotationBlock
566
     * @return Struct
567
     */
568
    protected function addStructPropertiesToAnnotationBlockUses(PhpAnnotationBlock $annotationBlock)
569
    {
570 198
        foreach ($this->getModelAttributes() as $attribute) {
571
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $this->getModel()->getPackagedName(), $attribute->getSetterName())));
572 198
        }
573 198
        return $this;
574 99
    }
575 198
    /**
576
     * @param PhpAnnotationBlock $annotationBlock
577
     * @return Struct
578
     */
579
    protected function addStructPropertiesToAnnotationBlockParams(PhpAnnotationBlock $annotationBlock)
580
    {
581 198
        foreach ($this->getModelAttributes() as $attribute) {
582
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()))));
583 198
        }
584 198
        return $this;
585 99
    }
586 198
    /**
587
     * @param PhpMethod $method
588
     * @return PhpAnnotationBlock
589
     */
590
    protected function getStructMethodsAddToAnnotationBlock(PhpMethod $method)
591
    {
592 114
        $attributeName = str_replace('addTo', '', $method->getName());
593
        $attribute = $this->getModel()->getAttribute($attributeName);
594 114
        if (!$attribute instanceof StructAttributeModel) {
595 114
            $attribute = $this->getModel()->getAttribute(lcfirst($attributeName));
596 114
        }
597 48
        $model = $this->getRestrictionFromStructAttribute($attribute);
598 24
        $annotationBlock = new PhpAnnotationBlock();
599 114
        if ($attribute instanceof StructAttributeModel) {
600 114
            $annotationBlock->addChild(sprintf('Add item to %s value', $attribute->getCleanName()));
601 114
            if ($model instanceof StructModel) {
602 114
                $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)));
603 114
            }
604 30
            $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)));
605 15
        }
606 114
        return $annotationBlock;
607 57
    }
608 114
    /**
609
     * @param PhpMethod $method
610
     * @return PhpAnnotationBlock
611
     */
612
    protected function getStructMethodsValidateAnnotationBlock(PhpMethod $method)
613
    {
614 318
        $methodName = lcfirst(substr($method->getName(), strpos($method->getName(), 'ValuesFrom') + strlen('ValuesFrom')));
615
        return new PhpAnnotationBlock([
616 318
            new PhpAnnotation(PhpAnnotation::NO_NAME, sprintf('This method is responsible for validating the values passed to the method %s', $methodName), self::ANNOTATION_LONG_LENGTH),
617
            new PhpAnnotation(PhpAnnotation::NO_NAME, sprintf('This method is willingly generated in order to preserve the one-line inline validation within the %s method', $methodName), self::ANNOTATION_LONG_LENGTH),
618
            new PhpAnnotation(self::ANNOTATION_PARAM, 'array $values'),
619
            new PhpAnnotation(self::ANNOTATION_RETURN, 'string'),
620
        ]);
621
    }
622
    /**
623
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getModel()
624 270
     * @return StructModel
625
     */
626 270
    public function getModel()
627 6
    {
628
        return parent::getModel();
629 264
    }
630
    /**
631
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::setModel()
632
     * @throws \InvalidArgumentException
633
     * @param AbstractModel $model
634
     * @return StructArray
635
     */
636
    public function setModel(AbstractModel $model)
637
    {
638
        if (!$model instanceof StructModel) {
639
            throw new \InvalidArgumentException('Model must be an instance of a Struct', __LINE__);
640
        }
641
        return parent::setModel($model);
642
    }
643
    /**
644
     * @param PhpMethod $method
645
     * @param StructAttribute $attribute
646
     * @param $parameterName
647
     * @param bool $itemType
648
     */
649
    protected function applyRules(PhpMethod $method, StructAttribute $attribute, $parameterName, $itemType = false)
650
    {
651
        if ($this->getGenerator()->getOptionValidation()) {
652
            $rules = new Rules($this, $method, $attribute, $this->methods);
653
            $rules->applyRules($parameterName, $itemType);
654
        }
655
    }
656
}
657