Passed
Push — feature/issue-257 ( 6fa0ed )
by Mikaël
08:52
created

Struct::addStructMethodGetBody()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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