Completed
Push — feature/issue-41 ( 00c62e...10c3f2 )
by Mikaël
23:17
created

addStructMethodsGetAnnotationBlockFromXmlAttribute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
ccs 10
cts 10
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 56
    protected function getStructMethodParameterType(StructAttributeModel $attribute, $returnArrayType = true)
147
    {
148 56
        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 16
            $method = new PhpMethod(sprintf('addTo%s', ucfirst($attribute->getCleanName())), array(
173 16
                new PhpFunctionParameter('item', PhpFunctionParameter::NO_VALUE, $this->getStructMethodParameterType($attribute, false)),
174 12
            ));
175 16
            $this->addStructMethodAddToBody($method, $attribute);
176 16
            $methods->add($method);
177 12
        }
178 76
        return $this;
179
    }
180
    /**
181
     * @param PhpMethod $method
182
     * @param StructAttributeModel $attribute
183
     * @return Struct
184
     */
185 16
    protected function addStructMethodAddToBody(PhpMethod $method, StructAttributeModel $attribute)
186
    {
187 16
        $this->addStructMethodSetBodyForRestriction($method, $attribute, 'item');
188
        $method
189 16
            ->addChild(sprintf('$this->%s[] = $item;', $attribute->getCleanName()))
190 16
            ->addChild('return $this;');
191 16
        return $this;
192
    }
193
    /**
194
     * @param MethodContainer $methods
195
     * @param StructAttributeModel $attribute
196
     * @return Struct
197
     */
198 56
    protected function addStructMethodSet(MethodContainer $methods, StructAttributeModel $attribute)
199
    {
200 56
        $method = new PhpMethod($attribute->getSetterName(), array(
201 56
            $this->getStructMethodParameter($attribute, true, null),
202 42
        ));
203 56
        $this->addStructMethodSetBody($method, $attribute);
204 56
        $methods->add($method);
205 56
        return $this;
206
    }
207
    /**
208
     * @param PhpMethod $method
209
     * @param StructAttributeModel $attribute
210
     * @return Struct
211
     */
212 76
    protected function addStructMethodSetBody(PhpMethod $method, StructAttributeModel $attribute)
213
    {
214 57
        return $this
215 76
            ->addStructMethodSetBodyForRestriction($method, $attribute)
216 76
            ->addStructMethodSetBodyForArray($method, $attribute)
217 76
            ->addStructMethodSetBodyAssignment($method, $attribute)
218 76
            ->addStructMethodSetBodyReturn($method);
219
    }
220
    /**
221
     * @param PhpMethod $method
222
     * @param StructAttributeModel $attribute
223
     * @return Struct
224
     */
225 76
    protected function addStructMethodSetBodyAssignment(PhpMethod $method, StructAttributeModel $attribute)
226
    {
227 76
        $method->addChild($this->getStructMethodSetBodyAssignment($attribute));
228 76
        return $this;
229
    }
230
    /**
231
     * @param PhpMethod $method
232
     * @return Struct
233
     */
234 76
    protected function addStructMethodSetBodyReturn(PhpMethod $method)
235
    {
236 76
        $method->addChild('return $this;');
237 76
        return $this;
238
    }
239
    /**
240
     * @param PhpMethod $method
241
     * @param StructAttributeModel $attribute
242
     * @param string $parameterName
243
     * @return Struct
244
     */
245 56
    protected function addStructMethodSetBodyForRestriction(PhpMethod $method, StructAttributeModel $attribute, $parameterName = null)
246
    {
247 56
        if (($model = $this->getModelFromStructAttribute($attribute)) instanceof StructModel && $model->getIsRestriction() && !$attribute->isArray()) {
248 32
            $parameterName = empty($parameterName) ? lcfirst($attribute->getCleanName()) : $parameterName;
249
            $method
250 32
                ->addChild(sprintf('if (!%s::%s($%s)) {', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID, $parameterName))
251 32
                    ->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))
252 32
                ->addChild('}');
253 24
        }
254 56
        return $this;
255
    }
256
    /**
257
     * @param PhpMethod $method
258
     * @param StructAttributeModel $attribute
259
     * @return Struct
260
     */
261 76
    protected function addStructMethodSetBodyForArray(PhpMethod $method, StructAttributeModel $attribute)
262
    {
263 76
        if ($attribute->isArray()) {
264 16
            $model = $this->getModelFromStructAttribute($attribute);
265 16
            $parameterName = lcfirst($attribute->getCleanName());
266 16
            if ($model instanceof StructModel && $model->getIsRestriction()) {
267
                $method
268 4
                    ->addChild('$invalidValues = array();')
269 4
                    ->addChild(sprintf('array_walk($%s, function($item) {', $parameterName))
270 4
                        ->addChild($method->getIndentedString(sprintf('if (!%s::%s($item)) {', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID), 1))
271 4
                            ->addChild($method->getIndentedString('$invalidValues[] = var_export($item);', 2))
272 4
                        ->addChild($method->getIndentedString('}', 1))
273 4
                    ->addChild('});')
274 4
                    ->addChild('if (!empty($invalidValues)) {')
275 4
                        ->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))
276 4
                    ->addChild('}');
277 3
            } else {
278
                $method
279 16
                    ->addChild(sprintf('array_walk($%s, function($item) {', $parameterName))
280 16
                        ->addChild($method->getIndentedString(sprintf('if (!%s) {', $this->getStructMethodSetBodyForArrayItemSanityCheck($attribute)), 1))
281 16
                            ->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))
282 16
                        ->addChild($method->getIndentedString('}', 1))
283 16
                    ->addChild('});');
284
            }
285 12
        }
286 76
        return $this;
287
    }
288
    /**
289
     * The second case which used PHP native functions is volontary limited by the native functions provided by PHP,
290
     * and the possible types defined in xsd_types.yml
291
     * @param StructAttributeModel $attribute
292
     */
293 16
    protected function getStructMethodSetBodyForArrayItemSanityCheck(StructAttributeModel $attribute)
294
    {
295 16
        $model = $this->getModelFromStructAttribute($attribute);
296 16
        $sanityCheck = 'false';
297 16
        if ($model instanceof StructModel) {
298 8
            $sanityCheck = sprintf('$item instanceof %s', $this->getStructAttributeType($attribute, true));
299 6
        } else {
300 12
            switch (self::getPhpType($attribute->getType())) {
301 9
                case 'int';
0 ignored issues
show
Coding Style introduced by
case statements should not use curly braces.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
302 12
                    $sanityCheck = 'is_int($item)';
303 12
                    break;
304 3
                case 'bool';
0 ignored issues
show
Coding Style introduced by
case statements should not use curly braces.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
305
                    $sanityCheck = 'is_bool($item)';
306
                    break;
307 3
                case 'float';
0 ignored issues
show
Coding Style introduced by
case statements should not use curly braces.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
308
                    $sanityCheck = 'is_float($item)';
309
                    break;
310 3
                case 'string';
0 ignored issues
show
Coding Style introduced by
case statements should not use curly braces.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
311 4
                    $sanityCheck = 'is_string($item)';
312 4
                    break;
313 9
            }
314
        }
315 16
        return $sanityCheck;
316
    }
317
    /**
318
     * @param StructAttributeModel $attribute
319
     * @return string
320
     */
321 76
    protected function getStructMethodSetBodyAssignment(StructAttributeModel $attribute)
322
    {
323 76
        if ($attribute->nameIsClean()) {
324 76
            $assignment = sprintf('$this->%s = $%s;', $attribute->getName(), lcfirst($attribute->getCleanName()));
325 57
        } else {
326
            $assignment = sprintf('$this->%s = $this->{\'%s\'} = $%s;', $attribute->getCleanName(), addslashes($attribute->getName()), lcfirst($attribute->getCleanName()));
327
        }
328 76
        return $assignment;
329
    }
330
    /**
331
     * @param PhpMethod $method
332
     * @param StructAttributeModel $attribute
333
     * @param string $thisAccess
334
     * @return Struct
335
     */
336 76
    protected function addStructMethodGetBody(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
337
    {
338 57
        return $this
339 76
            ->addStructMethodGetBodyForXml($method, $attribute, $thisAccess)
340 76
            ->addStructMethodGetBodyReturn($method, $attribute, $thisAccess);
341
    }
342
    /**
343
     * @param PhpMethod $method
344
     * @param StructAttributeModel $attribute
345
     * @param string $thisAccess
346
     * @return Struct
347
     */
348 76
    protected function addStructMethodGetBodyForXml(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
349
    {
350 76
        if ($attribute->isXml()) {
351
            $method
352 4
                ->addChild(sprintf('if (!empty($this->%1$s) && !($this->%1$s instanceof \DOMDocument)) {', $thisAccess))
353 4
                    ->addChild($method->getIndentedString('$dom = new \DOMDocument(\'1.0\', \'UTF-8\');', 1))
354 4
                    ->addChild($method->getIndentedString('$dom->formatOutput = true;', 1))
355 4
                    ->addChild($method->getIndentedString(sprintf('if ($dom->loadXML($this->%s)) {', $thisAccess), 1))
356 4
                    ->addChild($method->getIndentedString(sprintf('$this->%s($dom);', $attribute->getSetterName()), 2))
357 4
                    ->addChild($method->getIndentedString('}', 1))
358 4
                    ->addChild($method->getIndentedString('unset($dom);', 1))
359 4
                ->addChild('}');
360 3
        }
361 76
        return $this;
362
    }
363
    /**
364
     * @param PhpMethod $method
365
     * @param StructAttributeModel $attribute
366
     * @param string $thisAccess
367
     * @return Struct
368
     */
369 76
    protected function addStructMethodGetBodyReturn(PhpMethod $method, StructAttributeModel $attribute, $thisAccess)
370
    {
371 76
        $return = sprintf('return $this->%s;', $thisAccess);
372 76
        if ($attribute->isXml()) {
373 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);
374 3
        }
375 76
        $method->addChild($return);
376 76
        return $this;
377
    }
378
    /**
379
     * @param MethodContainer $methods
380
     * @param StructAttributeModel $attribute
381
     * @return Struct
382
     */
383 76
    protected function addStructMethodGet(MethodContainer $methods, StructAttributeModel $attribute)
384
    {
385 76
        $method = new PhpMethod($attribute->getGetterName(), $this->getStructMethodGetParameters($attribute));
386 76
        if ($attribute->nameIsClean()) {
387 76
            $thisAccess = sprintf('%s', $attribute->getName());
388 57
        } else {
389
            $thisAccess = sprintf('{\'%s\'}', addslashes($attribute->getName()));
390
        }
391 76
        $this->addStructMethodGetBody($method, $attribute, $thisAccess);
392 76
        $methods->add($method);
393 76
        return $this;
394
    }
395
    /**
396
     * @param StructAttributeModel $attribute
397
     * @return PhpFunctionParameter[]
398
     */
399 76
    protected function getStructMethodGetParameters(StructAttributeModel $attribute)
400
    {
401 76
        $parameters = array();
402 76
        if ($attribute->isXml()) {
403 4
            $parameters[] = new PhpFunctionParameter('asString', true);
404 3
        }
405 76
        return $parameters;
406
    }
407
    /**
408
     * @param MethodContainer $methods
409
     * @return Struct
410
     */
411 76
    protected function addStructMethodSetState(MethodContainer $methods)
412
    {
413 76
        $method = new PhpMethod(self::METHOD_SET_STATE, array(
414 76
            new PhpFunctionParameter('array', PhpFunctionParameter::NO_VALUE, 'array'),
415 76
        ), PhpMethod::ACCESS_PUBLIC, false, true);
416 76
        $method->addChild(sprintf('return parent::__set_state($array);'));
417 76
        $methods->add($method);
418 76
        return $this;
419
    }
420
    /**
421
     * @return PhpAnnotationBlock|null
422
     */
423 76
    protected function getMethodAnnotationBlock(PhpMethod $method)
424
    {
425 76
        return $this->getStructMethodAnnotationBlock($method);
426
    }
427
    /**
428
     * @param PhpMethod $method
429
     * @return PhpAnnotationBlock|null
430
     */
431 76
    protected function getStructMethodAnnotationBlock(PhpMethod $method)
432
    {
433 76
        $annotationBlock = null;
434 76
        switch ($method->getName()) {
435 76
            case self::METHOD_CONSTRUCT:
436 56
                $annotationBlock = $this->getStructMethodConstructAnnotationBlock();
437 56
                break;
438 76
            case self::METHOD_SET_STATE:
439 56
                $annotationBlock = $this->getStructMethodSetStateAnnotationBlock();
440 56
                break;
441 76
            case strpos($method->getName(), 'get') === 0:
442 76
            case strpos($method->getName(), 'set') === 0:
443 76
                $annotationBlock = $this->getStructMethodsSetAndGetAnnotationBlock($method);
444 76
                break;
445 16
            case strpos($method->getName(), 'addTo') === 0:
446 16
                $annotationBlock = $this->getStructMethodsAddToAnnotationBlock($method);
447 16
                break;
448 57
        }
449 76
        return $annotationBlock;
450
    }
451
    /**
452
     * @return PhpAnnotationBlock
453
     */
454 76
    protected function getStructMethodConstructAnnotationBlock()
455
    {
456 76
        $annotationBlock = new PhpAnnotationBlock(array(
457 76
            sprintf('Constructor method for %s', $this->getModel()->getName()),
458 57
        ));
459 76
        $this->addStructPropertiesToAnnotationBlock($annotationBlock);
460 76
        return $annotationBlock;
461
    }
462
    /**
463
     * @return PhpAnnotationBlock
464
     */
465 76
    protected function getStructMethodSetStateAnnotationBlock()
466
    {
467 76
        return new PhpAnnotationBlock(array(
468 76
            'Method called when an object has been exported with var_export() functions',
469 76
            'It allows to return an object instantiated with the values',
470 76
            new PhpAnnotation(self::ANNOTATION_SEE, sprintf('%s::__set_state()', $this->getModel()->getExtends(true))),
471 76
            new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::__set_state()', $this->getModel()->getExtends(true))),
472 76
            new PhpAnnotation(self::ANNOTATION_PARAM, 'array $array the exported values'),
473 76
            new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)),
474 57
        ));
475
    }
476
    /**
477
     * @param PhpMethod $method
478
     * @return PhpAnnotationBlock
479
     */
480 76
    protected function getStructMethodsSetAndGetAnnotationBlock(PhpMethod $method)
481
    {
482 76
        $parameters = $method->getParameters();
483 76
        $setOrGet = strtolower(substr($method->getName(), 0, 3));
484 76
        $parameter = array_shift($parameters);
485
        /**
486
         * Only set parameter must be based on a potential PhpFunctionParameter
487
         */
488 76
        if ($parameter instanceof PhpFunctionParameter && $setOrGet === 'set') {
489 76
            $parameterName = ucfirst($parameter->getName());
490 57
        } else {
491 76
            $parameterName = substr($method->getName(), 3);
492
        }
493 76
        $attribute = $this->getModel()->getAttribute($parameterName);
494 76
        if (!$attribute instanceof StructAttributeModel) {
495 40
            $parameterName = lcfirst($parameterName);
496 40
            $attribute = $this->getModel()->getAttribute($parameterName);
497 30
        }
498 76
        $setValueAnnotation = '%s %s value';
499 76
        $annotationBlock = new PhpAnnotationBlock();
500 76
        if ($attribute instanceof StructAttributeModel) {
501 76
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), $parameterName));
502 76
            $this->addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, $annotationBlock, $attribute);
503 57
        } elseif (empty($attribute)) {
504
            $annotationBlock->addChild(sprintf($setValueAnnotation, ucfirst($setOrGet), lcfirst($parameterName)));
505
            $this->addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, $annotationBlock, $parameterName);
506
        }
507 76
        return $annotationBlock;
508
    }
509
    /**
510
     * @param string $setOrGet
511
     * @param PhpAnnotationBlock $annotationBlock
512
     * @param StructAttributeModel $attribute
513
     * @return Struct
514
     */
515 76
    protected function addStructMethodsSetAndGetAnnotationBlockFromStructAttribute($setOrGet, PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
516
    {
517
        switch ($setOrGet) {
518 76
            case 'set':
519 76
                if (($model = $this->getModelFromStructAttribute($attribute)) instanceof StructModel && $model->getIsRestriction() && !$this->getModel()->isArray()) {
520
                    $annotationBlock
521 36
                        ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_VALUE_IS_VALID)))
522 36
                        ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $model->getPackagedName(true), StructEnum::METHOD_GET_VALID_VALUES)))
523 36
                        ->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
524 76
                } elseif ($attribute->isArray()) {
525 16
                    $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_THROWS, '\InvalidArgumentException'));
526 12
                }
527 76
                $this->addStructMethodsSetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()));
528 76
                break;
529 57
            case 'get':
530 76
                $this->addStructMethodsGetAnnotationBlockFromXmlAttribute($annotationBlock, $attribute);
531 76
                $this->addStructMethodsGetAnnotationBlock($annotationBlock, $this->getStructAttributeTypeGetAnnotation($attribute));
532 76
                break;
533
        }
534 76
        return $this;
535
    }
536
    /**
537
     * @param string $setOrGet
538
     * @param PhpAnnotationBlock $annotationBlock
539
     * @param string $attributeName
540
     * @return Struct
541
     */
542
    protected function addStructMethodsSetAndGetAnnotationBlockFromScalar($setOrGet, PhpAnnotationBlock $annotationBlock, $attributeName)
543
    {
544
        switch ($setOrGet) {
545
            case 'set':
546
                $this->addStructMethodsSetAnnotationBlock($annotationBlock, lcfirst($attributeName), lcfirst($attributeName));
547
                break;
548
            case 'get':
549
                $this->addStructMethodsGetAnnotationBlock($annotationBlock, lcfirst($attributeName));
550
                break;
551
        }
552
        return $this;
553
    }
554
    /**
555
     * @param PhpAnnotationBlock $annotationBlock
556
     * @param string $type
557
     * @param string $name
558
     * @return Struct
559
     */
560 76
    protected function addStructMethodsSetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $type, $name)
561
    {
562
        $annotationBlock
563 76
            ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $type, $name)))
564 76
            ->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)));
565 76
        return $this;
566
    }
567
    /**
568
     * @param PhpAnnotationBlock $annotationBlock
569
     * @param string $attribute
570
     * @return Struct
571
     */
572 76
    protected function addStructMethodsGetAnnotationBlock(PhpAnnotationBlock $annotationBlock, $attribute)
573
    {
574 76
        $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $attribute));
575 76
        return $this;
576
    }
577
    /**
578
     * @param PhpAnnotationBlock $annotationBlock
579
     * @param StructAttributeModel $attribute
580
     */
581 76
    protected function addStructMethodsGetAnnotationBlockFromXmlAttribute(PhpAnnotationBlock $annotationBlock, StructAttributeModel $attribute)
582
    {
583 76
        if ($attribute->isXml()) {
584
            $annotationBlock
585 4
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::loadXML()'))
586 4
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::hasChildNodes()'))
587 4
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMDocument::saveXML()'))
588 4
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, '\DOMNode::item()'))
589 4
                ->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $this->getModel()->getPackagedName(true), $attribute->getSetterName())))
590 4
                ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, 'bool $asString true: returns XML string, false: returns \DOMDocument'));
591 3
        }
592 76
    }
593
    /**
594
     * @param PhpAnnotationBlock $annotationBlock
595
     * @return Struct
596
     */
597 76
    protected function addStructPropertiesToAnnotationBlock(PhpAnnotationBlock $annotationBlock)
598
    {
599 57
        return $this
600 76
            ->addStructPropertiesToAnnotationBlockUses($annotationBlock)
601 76
            ->addStructPropertiesToAnnotationBlockParams($annotationBlock);
602
    }
603
    /**
604
     * @param PhpAnnotationBlock $annotationBlock
605
     * @return Struct
606
     */
607 76
    protected function addStructPropertiesToAnnotationBlockUses(PhpAnnotationBlock $annotationBlock)
608
    {
609 76
        foreach ($this->getModelAttributes() as $attribute) {
610 76
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_USES, sprintf('%s::%s()', $this->getModel()->getPackagedName(), $attribute->getSetterName())));
611 57
        }
612 76
        return $this;
613
    }
614
    /**
615
     * @param PhpAnnotationBlock $annotationBlock
616
     * @return Struct
617
     */
618 76
    protected function addStructPropertiesToAnnotationBlockParams(PhpAnnotationBlock $annotationBlock)
619
    {
620 76
        foreach ($this->getModelAttributes() as $attribute) {
621 76
            $annotationBlock->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $%s', $this->getStructAttributeTypeSetAnnotation($attribute), lcfirst($attribute->getCleanName()))));
622 57
        }
623 76
        return $this;
624
    }
625
    /**
626
     * @param PhpMethod $method
627
     * @return Struct
628
     */
629 16
    protected function getStructMethodsAddToAnnotationBlock(PhpMethod $method)
630
    {
631 16
        $attributeName = str_replace('addTo', '', $method->getName());
632 16
        $attribute = $this->getModel()->getAttribute($attributeName);
633 16
        $annotationBlock = new PhpAnnotationBlock();
634 16
        if ($attribute instanceof StructAttributeModel) {
635
            $annotationBlock
636 8
                ->addChild(sprintf('Add item to %s value', $attribute->getCleanName()))
637 8
                ->addChild(new PhpAnnotation(self::ANNOTATION_PARAM, sprintf('%s $item', $this->getStructAttributeTypeSetAnnotation($attribute, false))))
638 8
                ->addChild(new PhpAnnotation(self::ANNOTATION_RETURN, $this->getModel()->getPackagedName(true)));
639 6
        }
640 16
        return $annotationBlock;
641
    }
642
    /**
643
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::getModel()
644
     * @return StructModel
645
     */
646 124
    public function getModel()
647
    {
648 124
        return parent::getModel();
649
    }
650
    /**
651
     * @see \WsdlToPhp\PackageGenerator\File\AbstractModelFile::setModel()
652
     * @throws \InvalidaArgumentException
653
     * @param AbstractModel $model
654
     * @return StructArray
655
     */
656 124
    public function setModel(AbstractModel $model)
657
    {
658 124
        if (!$model instanceof StructModel) {
659 4
            throw new \InvalidArgumentException('Model must be an instance of a Struct', __LINE__);
660
        }
661 120
        return parent::setModel($model);
662
    }
663
}
664