Completed
Push — master ( ad8621...702d5d )
by Mikaël
52:05 queued 47:20
created

Struct::getStructMethodsSetAndGetAnnotationBlock()   B

Complexity

Conditions 8
Paths 36

Size

Total Lines 38
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 8

Importance

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