Completed
Pull Request — feature/issue-45 (#46)
by
unknown
26:03
created

Struct::addStructMethodGet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

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