Completed
Push — develop ( d22805...7fc434 )
by Mikaël
35:39
created

Struct   F

Complexity

Total Complexity 100

Size/Duplication

Total Lines 675
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 96.88%

Importance

Changes 8
Bugs 4 Features 3
Metric Value
wmc 100
c 8
b 4
f 3
lcom 1
cbo 12
dl 0
loc 675
ccs 248
cts 256
cp 0.9688
rs 3.5999

46 Methods

Rating   Name   Duplication   Size   Complexity  
A getClassConstants() 0 3 1
A getConstantAnnotationBlock() 0 3 1
A getModelAttributes() 0 4 1
A getClassProperties() 0 8 3
A getPropertyAnnotationBlock() 0 13 4
A getClassMethods() 0 7 1
A addStructMethodConstruct() 0 7 1
A addStructMethodConstructBody() 0 11 3
A addStructMethodConstructBodyForAttribute() 0 5 2
A getStructMethodParametersValues() 0 8 2
A getStructMethodParameter() 0 8 4
A addStructMethodSetBodyReturn() 0 5 1
A addStructMethodGetBody() 0 6 1
A getStructMethodParameterType() 0 4 1
A addStructMethodsSetAndGet() 0 10 2
A addStructMethodAddTo() 0 11 2
A addStructMethodAddToBody() 0 12 2
A addStructMethodSetBodyForAnyType() 0 8 1
A addStructMethodSet() 0 9 1
A addStructMethodSetBody() 0 11 2
A addStructMethodSetBodyAssignment() 0 5 1
A addStructMethodSetBodyForRestriction() 0 11 3
B addStructMethodSetBodyForArray() 0 27 3
B getStructMethodSetBodyForArrayItemSanityCheck() 0 24 6
A getStructMethodSetBodyAssignment() 0 9 2
A addStructMethodGetBodyForXml() 0 15 2
A addStructMethodGetBodyReturn() 0 9 2
A addStructMethodGet() 0 12 2
A getStructMethodGetParameters() 0 8 2
A addStructMethodSetState() 0 9 1
A getMethodAnnotationBlock() 0 4 1
B getStructMethodAnnotationBlock() 0 20 6
A getStructMethodConstructAnnotationBlock() 0 8 1
A getStructMethodSetStateAnnotationBlock() 0 11 1
B getStructMethodsSetAndGetAnnotationBlock() 0 29 6
B addStructMethodsSetAndGetAnnotationBlockFromStructAttribute() 0 21 6
A addStructMethodsSetAndGetAnnotationBlockFromScalar() 0 12 3
A addStructMethodsSetAnnotationBlock() 0 7 1
A addStructMethodsGetAnnotationBlock() 0 5 1
A addStructMethodsGetAnnotationBlockFromXmlAttribute() 0 12 2
A addStructPropertiesToAnnotationBlock() 0 6 1
A addStructPropertiesToAnnotationBlockUses() 0 7 2
A addStructPropertiesToAnnotationBlockParams() 0 7 2
B getStructMethodsAddToAnnotationBlock() 0 23 4
A getModel() 0 4 1
A setModel() 0 7 2

How to fix   Complexity   

Complex Class

Complex classes like Struct often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Struct, and based on these observations, apply Extract Interface, too.

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