Passed
Push — 2.x ( 270e0d...5f9cdf )
by Mikaël
24:20
created

Struct::addStructMethodSetState()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

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