Passed
Push — master ( ab6b67...a48167 )
by Mikaël
74:03 queued 50:14
created

Struct::getStructMethodSetStateAnnotationBlock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

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