Completed
Push — master ( ab2db9...9b8f8b )
by Mikaël
23:04
created

Struct::applyRules()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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