Completed
Push — master ( 9b8f8b...ad8621 )
by Mikaël
29:42
created

Struct::applyRules()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 4
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 2
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\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 294
    protected function getClassConstants(ConstantContainer $constants)
25
    {
26 294
    }
27
    /**
28
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getConstantAnnotationBlock()
29
     */
30
    protected function getConstantAnnotationBlock(PhpConstant $constant)
31
    {
32
    }
33
    /**
34
     * @param bool $includeInheritanceAttributes include the attributes of parent class, default parent attributes are not included. If true, then the array is an associative array containing and index "attribute" for the StructAttribute object and an index "model" for the Struct object.
35
     * @param bool $requiredFirst places the required attributes first, then the not required in order to have the _contrust method with the required attribute at first
36
     * @return StructAttributeContainer
37
     */
38 294
    protected function getModelAttributes($includeInheritanceAttributes = false, $requiredFirst = true)
39
    {
40 294
        return $this->getModel()->getAttributes($includeInheritanceAttributes, $requiredFirst);
41
    }
42
    /**
43
     * @param PropertyContainer $properties
44
     */
45 342
    protected function getClassProperties(PropertyContainer $properties)
46
    {
47 342
        if ($this->getModel()->getAttributes()->count() > 0) {
48 294
            foreach ($this->getModelAttributes() as $attribute) {
49 294
                $properties->add(new PhpProperty($attribute->getCleanName(), PhpProperty::NO_VALUE));
50 147
            }
51 147
        }
52 342
    }
53
    /**
54
     * @return PhpAnnotationBlock $property
55
     */
56 294
    protected function getPropertyAnnotationBlock(PhpProperty $property)
57
    {
58 294
        $annotationBlock = new PhpAnnotationBlock();
59 294
        $annotationBlock->addChild(sprintf('The %s', $property->getName()));
60 294
        $attribute = $this->getModel()->getAttribute($property->getName());
61 294
        if (!$attribute instanceof StructAttributeModel) {
62 6
            $attribute = $this->getModel()->getAttributeByCleanName($property->getName());
63 3
        }
64 294
        if ($attribute instanceof StructAttributeModel) {
0 ignored issues
show
introduced by
$attribute is always a sub-type of WsdlToPhp\PackageGenerator\Model\StructAttribute.
Loading history...
65 294
            $this->defineModelAnnotationsFromWsdl($annotationBlock, $attribute);
66 294
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_VAR, $this->getStructAttributeTypeSetAnnotation($attribute, true)));
67 147
        }
68 294
        return $annotationBlock;
69
    }
70 294
    protected function fillClassMethods()
71
    {
72 147
        $this
73 294
            ->addStructMethodConstruct()
74 294
            ->addStructMethodsSetAndGet()
75 294
            ->addStructMethodSetState();
76 294
    }
77
    /**
78
     * @return Struct
79
     */
80 294
    protected function addStructMethodConstruct()
81
    {
82 294
        $method = new PhpMethod(self::METHOD_CONSTRUCT, $this->getStructMethodParametersValues());
83 294
        $this->addStructMethodConstructBody($method);
84 294
        $this->methods->add($method);
85 294
        return $this;
86
    }
87
    /**
88
     * @param PhpMethod $method
89
     * @return Struct
90
     */
91 294
    protected function addStructMethodConstructBody(PhpMethod $method)
92
    {
93 294
        $count = $this->getModelAttributes()->count();
94 294
        foreach ($this->getModelAttributes() as $index => $attribute) {
95 294
            if ($index === 0) {
96 294
                $method->addChild('$this');
97 147
            }
98 294
            $this->addStructMethodConstructBodyForAttribute($method, $attribute, $count - 1 === $index);
99 147
        }
100 294
        return $this;
101
    }
102
    /**
103
     * @param PhpMethod $method
104
     * @param StructAttributeModel $attribute
105
     * @param bool $isLast
106
     * @return Struct
107
     */
108 294
    protected function addStructMethodConstructBodyForAttribute(PhpMethod $method, StructAttributeModel $attribute, $isLast)
109
    {
110 294
        $uniqueString = $attribute->getUniqueString($attribute->getCleanName(), 'method');
111 294
        $method->addChild($method->getIndentedString(sprintf('->%s($%s)%s', $attribute->getSetterName(), lcfirst($uniqueString), $isLast ? ';' : ''), 1));
112 294
        return $this;
113
    }
114
    /**
115
     * @return PhpFunctionParameter[]
116
     */
117 294
    protected function getStructMethodParametersValues()
118
    {
119 294
        $parametersValues = [];
120 294
        foreach ($this->getModelAttributes() as $attribute) {
121 294
            $parametersValues[] = $this->getStructMethodParameter($attribute, true);
122 147
        }
123 294
        return $parametersValues;
124
    }
125
    /**
126
     * @param StructAttributeModel $attribute
127
     * @param bool $lowCaseFirstLetter
128
     * @param mixed $defaultValue
129
     * @return PhpFunctionParameter
130
     */
131 294
    protected function getStructMethodParameter(StructAttributeModel $attribute, $lowCaseFirstLetter = false, $defaultValue = null)
132
    {
133
        try {
134 294
            $uniqueString = $attribute->getUniqueString($attribute->getCleanName(), 'method');
135 294
            return new PhpFunctionParameter($lowCaseFirstLetter ? lcfirst($uniqueString) : $uniqueString, isset($defaultValue) ? $defaultValue : $attribute->getDefaultValue(), $this->getStructMethodParameterType($attribute));
136
        } catch (\InvalidArgumentException $exception) {
137
            throw new \InvalidArgumentException(sprintf('Unable to create function parameter for struct "%s" with type "%s" for attribute "%s"', $this->getModel()->getName(), var_export($this->getStructMethodParameterType($attribute), true), $attribute->getName()), __LINE__, $exception);
138
        }
139
    }
140
    /**
141
     * @param StructAttributeModel $attribute
142
     * @param bool $returnArrayType
143
     * @return string|null
144
     */
145 294
    protected function getStructMethodParameterType(StructAttributeModel $attribute, $returnArrayType = true)
146
    {
147 294
        return self::getValidType($this->getStructAttributeTypeHint($attribute, $returnArrayType), $this->getGenerator()->getOptionXsdTypesPath(), null);
148
    }
149
    /**
150
     * @return Struct
151
     */
152 294
    protected function addStructMethodsSetAndGet()
153
    {
154 294
        foreach ($this->getModelAttributes() as $attribute) {
155 147
            $this
156 294
                ->addStructMethodGet($attribute)
157 294
                ->addStructMethodSet($attribute)
158 294
                ->addStructMethodAddTo($attribute);
159 147
        }
160 294
        return $this;
161
    }
162
    /**
163
     * @param StructAttributeModel $attribute
164
     * @return Struct
165
     */
166 294
    protected function addStructMethodAddTo(StructAttributeModel $attribute)
167
    {
168 294
        if ($attribute->isArray()) {
169 150
            $method = new PhpMethod(sprintf('addTo%s', ucfirst($attribute->getCleanName())), [
170 150
                new PhpFunctionParameter('item', PhpFunctionParameter::NO_VALUE, $this->getStructMethodParameterType($attribute, false)),
171 75
            ]);
172 150
            $this->addStructMethodAddToBody($method, $attribute);
173 150
            $this->methods->add($method);
174 75
        }
175 294
        return $this;
176
    }
177
    /**
178
     * @param PhpMethod $method
179
     * @param StructAttributeModel $attribute
180
     * @return Struct
181
     */
182 150
    protected function addStructMethodAddToBody(PhpMethod $method, StructAttributeModel $attribute)
183
    {
184 150
        if ($this->getGenerator()->getOptionValidation()) {
185 150
            $this->applyRules($method, $attribute, 'item', true);
186 75
        }
187
        $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 294
    protected function addStructMethodSet(StructAttributeModel $attribute)
197
    {
198 294
        $method = new PhpMethod($attribute->getSetterName(), [
199 294
            $this->getStructMethodParameter($attribute, true, null),
200 147
        ]);
201 294
        $this->addStructMethodSetBody($method, $attribute);
202 294
        $this->methods->add($method);
203 294
        return $this;
204
    }
205
    /**
206
     * @param PhpMethod $method
207
     * @param StructAttributeModel $attribute
208
     * @return Struct
209
     */
210 294
    protected function addStructMethodSetBody(PhpMethod $method, StructAttributeModel $attribute)
211
    {
212 294
        if ($this->getGenerator()->getOptionValidation()) {
213 288
            $uniqueString = $attribute->getUniqueString($attribute->getCleanName());
214 288
            $this->applyRules($method, $attribute, lcfirst($uniqueString));
215 144
        }
216 294
        return $this->addStructMethodSetBodyAssignment($method, $attribute)->addStructMethodSetBodyReturn($method);
217
    }
218
    /**
219
     * @param PhpMethod $method
220
     * @param StructAttributeModel $attribute
221
     * @return Struct
222
     */
223 294
    protected function addStructMethodSetBodyAssignment(PhpMethod $method, StructAttributeModel $attribute)
224
    {
225 294
        $uniqueString = $attribute->getUniqueString($attribute->getCleanName());
226 294
        $parameterName = lcfirst($uniqueString);
227 294
        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 282
            $method->addChild($this->getStructMethodSetBodyAssignment($attribute, $parameterName));
236
        }
237 294
        return $this;
238
    }
239
    /**
240
     * @param PhpMethod $method
241
     * @return Struct
242
     */
243 294
    protected function addStructMethodSetBodyReturn(PhpMethod $method)
244
    {
245 294
        $method->addChild('return $this;');
246 294
        return $this;
247
    }
248
    /**
249
     * @param StructAttributeModel $attribute
250
     * @param string $parameterName
251
     * @return string
252
     */
253 294
    protected function getStructMethodSetBodyAssignment(StructAttributeModel $attribute, $parameterName)
254
    {
255 294
        $prefix = '$';
256 294
        if ($this->isAttributeAList($attribute)) {
257 18
            $prefix = '';
258 18
            $parameterName = sprintf('is_array($%1$s) ? implode(\' \', $%1$s) : null', $parameterName);
259 294
        } 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 294
        if ($attribute->nameIsClean()) {
264 294
            $assignment = sprintf('$this->%s = %s%s;', $attribute->getName(), $prefix, $parameterName);
265 147
        } else {
266 6
            $assignment = sprintf('$this->%s = $this->{\'%s\'} = %s%s;', $attribute->getCleanName(), addslashes($attribute->getName()), $prefix, $parameterName);
267
        }
268 294
        return $assignment;
269
    }
270
    /**
271
     * @param PhpMethod $method
272
     * @param StructAttributeModel $attribute
273
     * @param string $thisAccess
274
     * @return Struct
275
     */
276 294
    protected function addStructMethodGetBody(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
277
    {
278 294
        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 294
    protected function addStructMethodGetBodyReturn(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
287
    {
288 294
        $return = sprintf('return $this->%s;', $thisAccess);
289 294
        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 294
        } elseif ($attribute->getRemovableFromRequest() || $attribute->isAChoice()) {
302 54
            $return = sprintf('return isset($this->%1$s) ? $this->%1$s : null;', $thisAccess);
303 27
        }
304 294
        $method->addChild($return);
305 294
        return $this;
306
    }
307
    /**
308
     * @param StructAttributeModel $attribute
309
     * @return Struct
310
     */
311 294
    protected function addStructMethodGet(StructAttributeModel $attribute)
312
    {
313 294
        $method = new PhpMethod($attribute->getGetterName(), $this->getStructMethodGetParameters($attribute));
314 294
        if ($attribute->nameIsClean()) {
315 294
            $thisAccess = sprintf('%s', $attribute->getName());
316 147
        } else {
317 6
            $thisAccess = sprintf('{\'%s\'}', addslashes($attribute->getName()));
318
        }
319 294
        $this->addStructMethodGetBody($method, $attribute, $thisAccess);
320 294
        $this->methods->add($method);
321 294
        return $this;
322
    }
323
    /**
324
     * @param StructAttributeModel $attribute
325
     * @return PhpFunctionParameter[]
326
     */
327 294
    protected function getStructMethodGetParameters(StructAttributeModel $attribute)
328
    {
329 294
        $parameters = [];
330 294
        if ($attribute->isXml()) {
331 6
            $parameters[] = new PhpFunctionParameter('asString', true);
332 3
        }
333 294
        return $parameters;
334
    }
335
    /**
336
     * @return Struct
337
     */
338 294
    protected function addStructMethodSetState()
339
    {
340 294
        $method = new PhpMethod(self::METHOD_SET_STATE, [
341 294
            new PhpFunctionParameter('array', PhpFunctionParameter::NO_VALUE, 'array'),
342 294
        ], PhpMethod::ACCESS_PUBLIC, false, true);
343 294
        $method->addChild(sprintf('return parent::__set_state($array);'));
344 294
        $this->methods->add($method);
345 294
        return $this;
346
    }
347
    /**
348
     * @return PhpAnnotationBlock|null
349
     */
350 294
    protected function getMethodAnnotationBlock(PhpMethod $method)
351
    {
352 294
        return $this->getStructMethodAnnotationBlock($method);
353
    }
354
    /**
355
     * @param PhpMethod $method
356
     * @return PhpAnnotationBlock|null
357
     */
358 294
    protected function getStructMethodAnnotationBlock(PhpMethod $method)
359
    {
360 294
        $annotationBlock = null;
361 294
        switch ($method->getName()) {
362 294
            case self::METHOD_CONSTRUCT:
363 294
                $annotationBlock = $this->getStructMethodConstructAnnotationBlock();
364 294
                break;
365 294
            case self::METHOD_SET_STATE:
366 294
                $annotationBlock = $this->getStructMethodSetStateAnnotationBlock();
367 294
                break;
368 294
            case 0 === mb_strpos($method->getName(), 'get'):
369 294
            case 0 === mb_strpos($method->getName(), 'set'):
370 294
                $annotationBlock = $this->getStructMethodsSetAndGetAnnotationBlock($method);
371 294
                break;
372 192
            case 0 === mb_strpos($method->getName(), 'addTo'):
373 150
                $annotationBlock = $this->getStructMethodsAddToAnnotationBlock($method);
374 150
                break;
375 192
            case false !== mb_strpos($method->getName(), 'ForUnionConstraintsFrom'):
376 12
                $annotationBlock = $this->getStructMethodsValidateUnionAnnotationBlock($method);
377 12
                break;
378 180
            case false !== mb_strpos($method->getName(), 'ForArrayConstraintsFrom'):
379 162
                $annotationBlock = $this->getStructMethodsValidateArrayAnnotationBlock($method);
380 162
                break;
381 36
            case false !== mb_strpos($method->getName(), 'ForChoiceConstraintsFrom'):
382 24
                $annotationBlock = $this->getStructMethodsValidateChoiceAnnotationBlock($method);
383 24
                break;
384 12
            case false !== mb_strpos($method->getName(), 'MaxLengthConstraintFrom'):
385 12
                $annotationBlock = $this->getStructMethodsValidateLengthAnnotationBlock($method, 'max');
386 12
                break;
387 12
            case false !== mb_strpos($method->getName(), 'MinLengthConstraintFrom'):
388 12
                $annotationBlock = $this->getStructMethodsValidateLengthAnnotationBlock($method, 'min');
389 12
                break;
390
            case false !== mb_strpos($method->getName(), 'LengthConstraintFrom'):
391
                $annotationBlock = $this->getStructMethodsValidateLengthAnnotationBlock($method);
392
                break;
393 147
        }
394 294
        return $annotationBlock;
395
    }
396
    /**
397
     * @return PhpAnnotationBlock
398
     */
399 294
    protected function getStructMethodConstructAnnotationBlock()
400
    {
401 294
        $annotationBlock = new PhpAnnotationBlock([
402 294
            sprintf('Constructor method for %s', $this->getModel()->getName()),
403 147
        ]);
404 294
        $this->addStructPropertiesToAnnotationBlock($annotationBlock);
405 294
        return $annotationBlock;
406
    }
407
    /**
408
     * @return PhpAnnotationBlock
409
     */
410 294
    protected function getStructMethodSetStateAnnotationBlock()
411
    {
412 294
        return new PhpAnnotationBlock([
413 294
            'Method called when an object has been exported with var_export() functions',
414 294
            'It allows to return an object instantiated with the values',
415 294
            new PhpAnnotation(self::ANNOTATION_SEE, sprintf('%s::__set_state()', $this->getModel()->getExtends(true))),
416 294
            new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::__set_state()', $this->getModel()->getExtends(true))),
417 294
            new PhpAnnotation(self::ANNOTATION_PARAM, 'array $array the exported values'),
418 294
            new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)),
419 147
        ]);
420
    }
421
    /**
422
     * @param PhpMethod $method
423
     * @return PhpAnnotationBlock
424
     */
425 294
    protected function getStructMethodsSetAndGetAnnotationBlock(PhpMethod $method)
426
    {
427 294
        $parameters = $method->getParameters();
428 294
        $setOrGet = mb_strtolower(mb_substr($method->getName(), 0, 3));
429 294
        $parameter = array_shift($parameters);
430
        /**
431
         * Only set parameter must be based on a potential PhpFunctionParameter
432
         */
433 294
        if ($parameter instanceof PhpFunctionParameter && $setOrGet === 'set') {
434 294
            $parameterName = ucfirst($parameter->getName());
435 147
        } else {
436 294
            $parameterName = mb_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 294
        $parameterName = preg_replace('/(_\d+)/', '', $parameterName);
442 294
        $attribute = $this->getModel()->getAttribute($parameterName);
443 294
        if (!$attribute instanceof StructAttributeModel) {
444 120
            $attribute = $this->getModel()->getAttributeByCleanName($parameterName);
445 60
        }
446 294
        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 294
        $setValueAnnotation = '%s %s value';
454 294
        $annotationBlock = new PhpAnnotationBlock();
455 294
        if ($attribute instanceof StructAttributeModel) {
0 ignored issues
show
introduced by
$attribute is always a sub-type of WsdlToPhp\PackageGenerator\Model\StructAttribute.
Loading history...
456 294
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), $parameterName));
457 294
            $this->addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, $annotationBlock, $attribute);
458 147
        } elseif (empty($attribute)) {
459 6
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), lcfirst($parameterName)));
460 6
            $this->addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, $annotationBlock, $parameterName);
461 3
        }
462 294
        return $annotationBlock;
463
    }
464
    /**
465
     * @param string $setOrGet
466
     * @param PhpAnnotationBlock $annotationBlock
467
     * @param StructAttributeModel $attribute
468
     * @return Struct
469
     */
470 294
    protected function addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
471
    {
472 49
        switch ($setOrGet) {
473 294
            case 'set':
474 294
                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 294
                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 294
                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 294
                if ($this->getGenerator()->getOptionValidation()) {
487 288
                    if ($attribute->isAChoice()) {
488 24
                        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
489 12
                    }
490 288
                    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 285
                    } elseif ($attribute->isArray()) {
496 144
                        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
497 72
                    }
498 144
                }
499 294
                $this->addStructMethodsSetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()));
500 294
                break;
501 294
            case 'get':
502 294
                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 147
                $this
506 294
                    ->addStructMethodsGetAnnotationBlockFromXmlAttribute($annotationBlock, $attribute)
507 294
                    ->addStructMethodsGetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeGetAnnotation($attribute));
508 294
                break;
509
        }
510 294
        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 294
    protected function addStructMethodsSetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $type, $name)
537
    {
538 294
        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $type, $name)))->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)));
539 294
        return $this;
540
    }
541
    /**
542
     * @param PhpAnnotationBlock $annotationBlock
543
     * @param string $attributeType
544
     * @return Struct
545
     */
546 294
    protected function addStructMethodsGetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $attributeType)
547
    {
548 294
        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $attributeType));
549 294
        return $this;
550
    }
551
    /**
552
     * @param PhpAnnotationBlock $annotationBlock
553
     * @param StructAttributeModel $attribute
554
     * @return Struct
555
     */
556 294
    protected function addStructMethodsGetAnnotationBlockFromXmlAttribute(PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
557
    {
558 294
        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 294
        return $this;
564
    }
565
    /**
566
     * @param PhpAnnotationBlock $annotationBlock
567
     * @return Struct
568
     */
569 294
    protected function addStructPropertiesToAnnotationBlock(PhpAnnotationBlock $annotationBlock)
570
    {
571 294
        return $this->addStructPropertiesToAnnotationBlockUses($annotationBlock)->addStructPropertiesToAnnotationBlockParams($annotationBlock);
572
    }
573
    /**
574
     * @param PhpAnnotationBlock $annotationBlock
575
     * @return Struct
576
     */
577 294
    protected function addStructPropertiesToAnnotationBlockUses(PhpAnnotationBlock $annotationBlock)
578
    {
579 294
        foreach ($this->getModelAttributes() as $attribute) {
580 294
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $this->getModel()->getPackagedName(), $attribute->getSetterName())));
581 147
        }
582 294
        return $this;
583
    }
584
    /**
585
     * @param PhpAnnotationBlock $annotationBlock
586
     * @return Struct
587
     */
588 294
    protected function addStructPropertiesToAnnotationBlockParams(PhpAnnotationBlock $annotationBlock)
589
    {
590 294
        foreach ($this->getModelAttributes() as $attribute) {
591 294
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()))));
592 147
        }
593 294
        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(mb_substr($method->getName(), mb_strpos($method->getName(), 'ForArrayConstraintsFrom') + mb_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(mb_substr($method->getName(), mb_strpos($method->getName(), 'ForUnionConstraintsFrom') + mb_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(mb_substr($method->getName(), mb_strpos($method->getName(), 'ForChoiceConstraintsFrom') + mb_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(mb_substr($method->getName(), mb_strpos($method->getName(), $replace) + mb_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 372
    public function getModel()
683
    {
684 372
        return parent::getModel();
685
    }
686
    /**
687
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::setModel()
688
     * @throws \InvalidArgumentException
689
     * @param AbstractModel $model
690
     * @return StructArray
691
     */
692 372
    public function setModel(AbstractModel $model)
693
    {
694 372
        if (!$model instanceof StructModel) {
695 6
            throw new \InvalidArgumentException('Model must be an instance of a Struct', __LINE__);
696
        }
697 366
        return parent::setModel($model);
698
    }
699
    /**
700
     * @param PhpMethod $method
701
     * @param StructAttributeModel $attribute
702
     * @param $parameterName
703
     * @param bool $itemType
704
     */
705 288
    protected function applyRules(PhpMethod $method, StructAttributeModel $attribute, $parameterName, $itemType = false)
706
    {
707 288
        if ($this->getGenerator()->getOptionValidation()) {
708 288
            $rules = new Rules($this, $method, $attribute, $this->methods);
709 288
            $rules->applyRules($parameterName, $itemType);
710 144
        }
711 288
    }
712
}
713