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

Struct::addStructMethodsSetAnnotationBlock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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