Completed
Push — feature/issue-45 ( d6e400 )
by Mikaël
26:10 queued 23:22
created

getStructMethodSetBodyForArrayItemSanityCheck()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 25
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7.2944

Importance

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