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