Passed
Push — develop ( 644332...dd8711 )
by Mikaël
23:24 queued 11s
created

Struct::addStructMethodAddToBody()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3.0067

Importance

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