Passed
Push — 2.x ( bef6c0...34f135 )
by Mikaël
03:54
created

Struct::applyRules()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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