Completed
Push — feature/issue-168 ( ec3cb9...356d0d )
by Mikaël
25:19
created

Struct::getStructMethodAnnotationBlock()   C

Complexity

Conditions 12
Paths 12

Size

Total Lines 37
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 12.0832

Importance

Changes 0
Metric Value
cc 12
eloc 34
nc 12
nop 1
dl 0
loc 37
ccs 33
cts 36
cp 0.9167
crap 12.0832
rs 6.9666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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