Passed
Push — feature/issue-170 ( 2776fe )
by Mikaël
49:22
created

Struct::getStructMethodSetStateAnnotationBlock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 9
ccs 8
cts 8
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
    protected function getClassConstants(ConstantContainer $constants)
25
    {
26
    }
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
    protected function getModelAttributes($includeInheritanceAttributes = false, $requiredFirst = true)
39
    {
40
        return $this->getModel()->getAttributes($includeInheritanceAttributes, $requiredFirst);
41
    }
42
    /**
43
     * @param PropertyContainer $properties
44
     */
45
    protected function getClassProperties(PropertyContainer $properties)
46
    {
47
        if ($this->getModel()->getAttributes()->count() > 0) {
48
            foreach ($this->getModelAttributes() as $attribute) {
49
                $properties->add(new PhpProperty($attribute->getCleanName(), PhpProperty::NO_VALUE));
50
            }
51
        }
52
    }
53
    /**
54
     * @return PhpAnnotationBlock $property
55
     */
56
    protected function getPropertyAnnotationBlock(PhpProperty $property)
57
    {
58
        $annotationBlock = new PhpAnnotationBlock();
59
        $annotationBlock->addChild(sprintf('The %s', $property->getName()));
60
        $attribute = $this->getModel()->getAttribute($property->getName());
61
        if (!$attribute instanceof StructAttributeModel) {
62
            $attribute = $this->getModel()->getAttributeByCleanName($property->getName());
63
        }
64
        if ($attribute instanceof StructAttributeModel) {
0 ignored issues
show
introduced by
$attribute is always a sub-type of WsdlToPhp\PackageGenerator\Model\StructAttribute.
Loading history...
65
            $this->defineModelAnnotationsFromWsdl($annotationBlock, $attribute);
66
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_VAR, $this->getStructAttributeTypeSetAnnotation($attribute, true)));
67
        }
68
        return $annotationBlock;
69
    }
70
    protected function fillClassMethods()
71
    {
72
        $this
73
            ->addStructMethodConstruct()
74
            ->addStructMethodsSetAndGet();
75
    }
76
    /**
77
     * @return Struct
78
     */
79
    protected function addStructMethodConstruct()
80
    {
81
        if (0 < count($parameters = $this->getStructMethodParametersValues())) {
82
            $method = new PhpMethod(self::METHOD_CONSTRUCT, $parameters);
83
            $this->addStructMethodConstructBody($method);
84
            $this->methods->add($method);
85
        }
86
        return $this;
87
    }
88
    /**
89
     * @param PhpMethod $method
90
     * @return Struct
91
     */
92
    protected function addStructMethodConstructBody(PhpMethod $method)
93
    {
94
        $count = $this->getModelAttributes()->count();
95
        foreach ($this->getModelAttributes() as $index => $attribute) {
96
            if ($index === 0) {
97
                $method->addChild('$this');
98
            }
99
            $this->addStructMethodConstructBodyForAttribute($method, $attribute, $count - 1 === $index);
100
        }
101
        return $this;
102
    }
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
    {
111
        $uniqueString = $attribute->getUniqueString($attribute->getCleanName(), 'method');
112
        $method->addChild($method->getIndentedString(sprintf('->%s($%s)%s', $attribute->getSetterName(), lcfirst($uniqueString), $isLast ? ';' : ''), 1));
113
        return $this;
114
    }
115
    /**
116
     * @return PhpFunctionParameter[]
117
     */
118
    protected function getStructMethodParametersValues()
119
    {
120
        $parametersValues = [];
121
        foreach ($this->getModelAttributes() as $attribute) {
122
            $parametersValues[] = $this->getStructMethodParameter($attribute, true);
123
        }
124
        return $parametersValues;
125
    }
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
    {
134
        try {
135
            $uniqueString = $attribute->getUniqueString($attribute->getCleanName(), 'method');
136
            return new PhpFunctionParameter($lowCaseFirstLetter ? lcfirst($uniqueString) : $uniqueString, isset($defaultValue) ? $defaultValue : $attribute->getDefaultValue(), $this->getStructMethodParameterType($attribute), $attribute);
137
        } 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
    {
148
        return self::getValidType($this->getStructAttributeTypeHint($attribute, $returnArrayType), $this->getGenerator()->getOptionXsdTypesPath(), null);
149
    }
150
    /**
151
     * @return Struct
152
     */
153
    protected function addStructMethodsSetAndGet()
154
    {
155
        foreach ($this->getModelAttributes() as $attribute) {
156
            $this
157
                ->addStructMethodGet($attribute)
158
                ->addStructMethodSet($attribute)
159
                ->addStructMethodAddTo($attribute);
160
        }
161
        return $this;
162
    }
163
    /**
164
     * @param StructAttributeModel $attribute
165
     * @return Struct
166
     */
167
    protected function addStructMethodAddTo(StructAttributeModel $attribute)
168
    {
169
        if ($attribute->isArray()) {
170
            $method = new PhpMethod(sprintf('addTo%s', ucfirst($attribute->getCleanName())), [
171
                new PhpFunctionParameter('item', PhpFunctionParameter::NO_VALUE, $this->getStructMethodParameterType($attribute, false), $attribute),
172
            ]);
173
            $this->addStructMethodAddToBody($method, $attribute);
174
            $this->methods->add($method);
175
        }
176
        return $this;
177
    }
178
    /**
179
     * @param PhpMethod $method
180
     * @param StructAttributeModel $attribute
181
     * @return Struct
182
     */
183
    protected function addStructMethodAddToBody(PhpMethod $method, StructAttributeModel $attribute)
184
    {
185
        if ($this->getGenerator()->getOptionValidation()) {
186
            $this->applyRules($method, $attribute, 'item', true);
187
        }
188
189
        if ($attribute->nameIsClean()) {
190
            $assignment = sprintf('$this->%s[] = $item;', $attribute->getCleanName());
191
        } else {
192
            $assignment = sprintf('$this->%s[] = $this->{\'%s\'}[] = $item;', $attribute->getCleanName(), addslashes($attribute->getName()), $attribute->getCleanName());
193
        }
194
        $method
195
            ->addChild($assignment)
196
            ->addChild('return $this;');
197
        return $this;
198
    }
199
    /**
200
     * @param StructAttributeModel $attribute
201
     * @return Struct
202
     */
203
    protected function addStructMethodSet(StructAttributeModel $attribute)
204
    {
205
        $method = new PhpMethod($attribute->getSetterName(), [
206
            $this->getStructMethodParameter($attribute, true, null),
207
        ]);
208
        $this->addStructMethodSetBody($method, $attribute);
209
        $this->methods->add($method);
210
        return $this;
211
    }
212
    /**
213
     * @param PhpMethod $method
214
     * @param StructAttributeModel $attribute
215
     * @return Struct
216
     */
217
    protected function addStructMethodSetBody(PhpMethod $method, StructAttributeModel $attribute)
218
    {
219
        $parameters = $method->getParameters();
220
        $parameter = array_shift($parameters);
221
        $parameterName = is_string($parameter) ? $parameter : $parameter->getName();
222
        if ($this->getGenerator()->getOptionValidation()) {
223
            $this->applyRules($method, $attribute, $parameterName);
224
        }
225
        return $this
226
            ->addStructMethodSetBodyAssignment($method, $attribute, $parameterName)
227
            ->addStructMethodSetBodyReturn($method);
228
    }
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
    {
237
        if ($attribute->getRemovableFromRequest() || $attribute->isAChoice()) {
238
            $method
239
                ->addChild(sprintf('if (is_null($%1$s) || (is_array($%1$s) && empty($%1$s))) {', $parameterName))
240
                ->addChild($method->getIndentedString(sprintf('unset($this->%1$s%2$s);', $attribute->getCleanName(), $attribute->nameIsClean() ? '' : sprintf(', $this->{\'%s\'}', addslashes($attribute->getName()))), 1))
241
                ->addChild('} else {')
242
                ->addChild($method->getIndentedString($this->getStructMethodSetBodyAssignment($attribute, $parameterName), 1))
243
                ->addChild('}');
244
        } else {
245
            $method->addChild($this->getStructMethodSetBodyAssignment($attribute, $parameterName));
246
        }
247
        return $this;
248
    }
249
    /**
250
     * @param PhpMethod $method
251
     * @return Struct
252
     */
253
    protected function addStructMethodSetBodyReturn(PhpMethod $method)
254
    {
255
        $method->addChild('return $this;');
256
        return $this;
257
    }
258
    /**
259
     * @param StructAttributeModel $attribute
260
     * @param string $parameterName
261
     * @return string
262
     */
263
    protected function getStructMethodSetBodyAssignment(StructAttributeModel $attribute, $parameterName)
264
    {
265
        $prefix = '$';
266
        if ($this->isAttributeAList($attribute)) {
267
            $prefix = '';
268
            $parameterName = sprintf('is_array($%1$s) ? implode(\' \', $%1$s) : null', $parameterName);
269
        } elseif ($attribute->isXml()) {
270
            $prefix = '';
271
            $parameterName = sprintf('($%1$s instanceof \DOMDocument) && $%1$s->hasChildNodes() ? $%1$s->saveXML($%1$s->childNodes->item(0)) : $%1$s', $parameterName);
272
        }
273
        if ($attribute->nameIsClean()) {
274
            $assignment = sprintf('$this->%s = %s%s;', $attribute->getName(), $prefix, $parameterName);
275
        } else {
276
            $assignment = sprintf('$this->%s = $this->{\'%s\'} = %s%s;', $attribute->getCleanName(), addslashes($attribute->getName()), $prefix, $parameterName);
277
        }
278
        return $assignment;
279
    }
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
    {
288
        return $this->addStructMethodGetBodyReturn($method, $attribute, $thisAccess);
289
    }
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
    {
298
        $return = sprintf('return $this->%s;', $thisAccess);
299
        if ($attribute->isXml()) {
300
            $method
301
                ->addChild('$domDocument = null;')
302
                ->addChild(sprintf('if (!empty($this->%1$s) && !$asString) {', $thisAccess))
303
                ->addChild($method->getIndentedString('$domDocument = new \DOMDocument(\'1.0\', \'UTF-8\');', 1))
304
                ->addChild($method->getIndentedString(sprintf('$domDocument->loadXML($this->%s);', $thisAccess), 1))
305
                ->addChild('}');
306
            if ($attribute->getRemovableFromRequest() || $attribute->isAChoice()) {
307
                $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
            }
311
        } elseif ($attribute->getRemovableFromRequest() || $attribute->isAChoice()) {
312
            $return = sprintf('return isset($this->%1$s) ? $this->%1$s : null;', $thisAccess);
313
        }
314
        $method->addChild($return);
315
        return $this;
316
    }
317
    /**
318
     * @param StructAttributeModel $attribute
319
     * @return Struct
320
     */
321
    protected function addStructMethodGet(StructAttributeModel $attribute)
322
    {
323
        $method = new PhpMethod($attribute->getGetterName(), $this->getStructMethodGetParameters($attribute));
324
        if ($attribute->nameIsClean()) {
325
            $thisAccess = sprintf('%s', $attribute->getName());
326
        } else {
327
            $thisAccess = sprintf('{\'%s\'}', addslashes($attribute->getName()));
328
        }
329
        $this->addStructMethodGetBody($method, $attribute, $thisAccess);
330
        $this->methods->add($method);
331
        return $this;
332
    }
333
    /**
334
     * @param StructAttributeModel $attribute
335
     * @return PhpFunctionParameter[]
336
     */
337
    protected function getStructMethodGetParameters(StructAttributeModel $attribute)
338
    {
339
        $parameters = [];
340
        if ($attribute->isXml()) {
341
            $parameters[] = new PhpFunctionParameter('asString', true, null, $attribute);
342
        }
343
        return $parameters;
344
    }
345
    /**
346
     * @return PhpAnnotationBlock|null
347
     */
348
    protected function getMethodAnnotationBlock(PhpMethod $method)
349
    {
350
        return $this->getStructMethodAnnotationBlock($method);
351
    }
352
    /**
353
     * @param PhpMethod $method
354
     * @return PhpAnnotationBlock|null
355
     */
356
    protected function getStructMethodAnnotationBlock(PhpMethod $method)
357
    {
358
        $annotationBlock = null;
359
        switch ($method->getName()) {
360
            case self::METHOD_CONSTRUCT:
361
                $annotationBlock = $this->getStructMethodConstructAnnotationBlock();
362
                break;
363
            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
                break;
370
            case false !== mb_strpos($method->getName(), 'ForUnionConstraintsFrom'):
371
                $annotationBlock = $this->getStructMethodsValidateUnionAnnotationBlock($method);
372
                break;
373
            case false !== mb_strpos($method->getName(), 'ForArrayConstraintsFrom'):
374
                $annotationBlock = $this->getStructMethodsValidateArrayAnnotationBlock($method);
375
                break;
376
            case false !== mb_strpos($method->getName(), 'ForChoiceConstraintsFrom'):
377
                $annotationBlock = $this->getStructMethodsValidateChoiceAnnotationBlock($method);
378
                break;
379
            case false !== mb_strpos($method->getName(), 'MaxLengthConstraintFrom'):
380
                $annotationBlock = $this->getStructMethodsValidateLengthAnnotationBlock($method, 'max');
381
                break;
382
            case false !== mb_strpos($method->getName(), 'MinLengthConstraintFrom'):
383
                $annotationBlock = $this->getStructMethodsValidateLengthAnnotationBlock($method, 'min');
384
                break;
385
            case false !== mb_strpos($method->getName(), 'LengthConstraintFrom'):
386
                $annotationBlock = $this->getStructMethodsValidateLengthAnnotationBlock($method);
387
                break;
388
        }
389
        return $annotationBlock;
390
    }
391
    /**
392
     * @return PhpAnnotationBlock
393
     */
394
    protected function getStructMethodConstructAnnotationBlock()
395
    {
396
        $annotationBlock = new PhpAnnotationBlock([
397
            sprintf('Constructor method for %s', $this->getModel()->getName()),
398
        ]);
399
        $this->addStructPropertiesToAnnotationBlock($annotationBlock);
400
        return $annotationBlock;
401
    }
402
    /**
403
     * @param PhpMethod $method
404
     * @return PhpAnnotationBlock
405
     */
406
    protected function getStructMethodsSetAndGetAnnotationBlock(PhpMethod $method)
407
    {
408
        $parameters = $method->getParameters();
409
        $setOrGet = mb_strtolower(mb_substr($method->getName(), 0, 3));
410
        $parameter = array_shift($parameters);
411
        /**
412
         * Only set parameter must be based on a potential PhpFunctionParameter
413
         */
414
        if ($parameter instanceof PhpFunctionParameter && $setOrGet === 'set') {
415
            $parameterName = ucfirst($parameter->getName());
416
        } 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
         */
422
        $parameterName = preg_replace('/(_\d+)/', '', $parameterName);
423
        $attribute = $this->getModel()->getAttribute($parameterName);
424
        if (!$attribute instanceof StructAttributeModel) {
425
            $attribute = $this->getModel()->getAttributeByCleanName($parameterName);
426
        }
427
        if (!$attribute instanceof StructAttributeModel) {
0 ignored issues
show
introduced by
$attribute is always a sub-type of WsdlToPhp\PackageGenerator\Model\StructAttribute.
Loading history...
428
            $parameterName = lcfirst($parameterName);
429
            $attribute = $this->getModel()->getAttribute($parameterName);
430
            if (!$attribute instanceof StructAttributeModel) {
431
                $attribute = $this->getModel()->getAttributeByCleanName($parameterName);
432
            }
433
        }
434
        $setValueAnnotation = '%s %s value';
435
        $annotationBlock = new PhpAnnotationBlock();
436
        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
            $this->addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, $annotationBlock, $attribute);
439
        } elseif (empty($attribute)) {
440
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), lcfirst($parameterName)));
441
            $this->addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, $annotationBlock, $parameterName);
442
        }
443
        return $annotationBlock;
444
    }
445
    /**
446
     * @param string $setOrGet
447
     * @param PhpAnnotationBlock $annotationBlock
448
     * @param StructAttributeModel $attribute
449
     * @return Struct
450
     */
451
    protected function addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
452
    {
453
        switch ($setOrGet) {
454
            case 'set':
455
                if ($attribute->getRemovableFromRequest()) {
456
                    $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
                }
458
                if ($attribute->isAChoice()) {
459
                    $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
                }
461
                if ($attribute->isXml()) {
462
                    $annotationBlock
463
                        ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::hasChildNodes()'))
464
                        ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::saveXML()'))
465
                        ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMNode::item()'));
466
                }
467
                if ($this->getGenerator()->getOptionValidation()) {
468
                    if ($attribute->isAChoice()) {
469
                        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
470
                    }
471
                    if (($model = $this->getRestrictionFromStructAttribute($attribute)) instanceof StructModel) {
472
                        $annotationBlock
473
                            ->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
                break;
482
            case 'get':
483
                if ($attribute->getRemovableFromRequest()) {
484
                    $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
                }
486
                $this
487
                    ->addStructMethodsGetAnnotationBlockFromXmlAttribute($annotationBlock, $attribute)
488
                    ->addStructMethodsGetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeGetAnnotation($attribute));
489
                break;
490
        }
491
        return $this;
492
    }
493
    /**
494
     * @param string $setOrGet
495
     * @param PhpAnnotationBlock $annotationBlock
496
     * @param string $attributeName
497
     * @return Struct
498
     */
499
    protected function addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, PhpAnnotationBlock $annotationBlock, $attributeName)
500
    {
501
        switch ($setOrGet) {
502
            case 'set':
503
                $this->addStructMethodsSetAnnotationBlock($annotationBlock, lcfirst($attributeName), lcfirst($attributeName));
504
                break;
505
            case 'get':
506
                $this->addStructMethodsGetAnnotationBlock($annotationBlock, lcfirst($attributeName));
507
                break;
508
        }
509
        return $this;
510
    }
511
    /**
512
     * @param PhpAnnotationBlock $annotationBlock
513
     * @param string $type
514
     * @param string $name
515
     * @return Struct
516
     */
517
    protected function addStructMethodsSetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $type, $name)
518
    {
519
        $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
    }
522
    /**
523
     * @param PhpAnnotationBlock $annotationBlock
524
     * @param string $attributeType
525
     * @return Struct
526
     */
527
    protected function addStructMethodsGetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $attributeType)
528
    {
529
        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $attributeType));
530
        return $this;
531
    }
532
    /**
533
     * @param PhpAnnotationBlock $annotationBlock
534
     * @param StructAttributeModel $attribute
535
     * @return Struct
536
     */
537
    protected function addStructMethodsGetAnnotationBlockFromXmlAttribute(PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
538
    {
539
        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
     * @param PhpAnnotationBlock $annotationBlock
548
     * @return Struct
549
     */
550
    protected function addStructPropertiesToAnnotationBlock(PhpAnnotationBlock $annotationBlock)
551
    {
552
        return $this->addStructPropertiesToAnnotationBlockUses($annotationBlock)->addStructPropertiesToAnnotationBlockParams($annotationBlock);
553
    }
554
    /**
555
     * @param PhpAnnotationBlock $annotationBlock
556
     * @return Struct
557
     */
558
    protected function addStructPropertiesToAnnotationBlockUses(PhpAnnotationBlock $annotationBlock)
559
    {
560
        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
     * @return Struct
568
     */
569
    protected function addStructPropertiesToAnnotationBlockParams(PhpAnnotationBlock $annotationBlock)
570
    {
571
        foreach ($this->getModelAttributes() as $attribute) {
572
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()))));
573
        }
574
        return $this;
575
    }
576
    /**
577
     * @param PhpMethod $method
578
     * @return PhpAnnotationBlock
579
     */
580
    protected function getStructMethodsAddToAnnotationBlock(PhpMethod $method)
581
    {
582
        $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
            $annotationBlock->addChild(sprintf('Add item to %s value', $attribute->getCleanName()));
589
            if ($model instanceof StructModel) {
590
                $annotationBlock
591
                    ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID)))
592
                    ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES)));
593
            }
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
        return $annotationBlock;
600
    }
601
    /**
602
     * @param PhpMethod $method
603
     * @return PhpAnnotationBlock
604
     */
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
            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
            new PhpAnnotation(self::ANNOTATION_RETURN, 'string A non-empty message if the values does not match the validation rules'),
613
        ]);
614
    }
615
    /**
616
     * @param PhpMethod $method
617
     * @return PhpAnnotationBlock
618
     */
619
    protected function getStructMethodsValidateUnionAnnotationBlock(PhpMethod $method)
620
    {
621
        $methodName = lcfirst(mb_substr($method->getName(), mb_strpos($method->getName(), 'ForUnionConstraintsFrom') + mb_strlen('ForUnionConstraintsFrom')));
622
        return new PhpAnnotationBlock([
623
            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
            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
            new PhpAnnotation(self::ANNOTATION_PARAM, 'mixed $value'),
627
            new PhpAnnotation(self::ANNOTATION_RETURN, 'string A non-empty message if the values does not match the validation rules'),
628
        ]);
629
    }
630
    /**
631
     * @param PhpMethod $method
632
     * @return PhpAnnotationBlock
633
     */
634
    protected function getStructMethodsValidateChoiceAnnotationBlock(PhpMethod $method)
635
    {
636
        $methodName = lcfirst(mb_substr($method->getName(), mb_strpos($method->getName(), 'ForChoiceConstraintsFrom') + mb_strlen('ForChoiceConstraintsFrom')));
637
        return new PhpAnnotationBlock([
638
            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
            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
            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
            new PhpAnnotation(self::ANNOTATION_PARAM, 'mixed $value'),
642
            new PhpAnnotation(self::ANNOTATION_RETURN, 'string A non-empty message if the values does not match the validation rules'),
643
        ]);
644
    }
645
    /**
646
     * @param PhpMethod $method
647
     * @param string $type
648
     * @return PhpAnnotationBlock
649
     */
650
    protected function getStructMethodsValidateLengthAnnotationBlock(PhpMethod $method, $type = '')
651
    {
652
        $replace = sprintf('%sLengthConstraintFrom', ucfirst($type));
653
        $methodName = lcfirst(mb_substr($method->getName(), mb_strpos($method->getName(), $replace) + mb_strlen($replace)));
654
        return new PhpAnnotationBlock([
655
            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
            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
            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
            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
     * @return StructModel
665
     */
666
    public function getModel()
667
    {
668
        return parent::getModel();
669
    }
670
    /**
671
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::setModel()
672
     * @throws \InvalidArgumentException
673
     * @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
        }
681
        return parent::setModel($model);
682
    }
683
    /**
684
     * @param PhpMethod $method
685
     * @param StructAttributeModel $attribute
686
     * @param $parameterName
687
     * @param bool $itemType
688
     */
689
    protected function applyRules(PhpMethod $method, StructAttributeModel $attribute, $parameterName, $itemType = false)
690
    {
691
        if ($this->getGenerator()->getOptionValidation()) {
692
            $rules = new Rules($this, $method, $attribute, $this->methods);
693
            $rules->applyRules($parameterName, $itemType);
694
        }
695
    }
696
}
697