Completed
Push — develop ( 4181ca...d9b187 )
by Mikaël
56:49 queued 28:52
created

addStructMethodsSetAndGetAnnotationBlockFromStructAttribute()   C

Complexity

Conditions 8
Paths 9

Size

Total Lines 28
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8

Importance

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