Completed
Push — feature/issue-165 ( 83f642...d66719 )
by Mikaël
23:02 queued 18s
created

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