Completed
Push — feature/issue-183 ( 65e9db )
by Mikaël
28:51 queued 24:09
created

Struct   F

Complexity

Total Complexity 112

Size/Duplication

Total Lines 700
Duplicated Lines 0 %

Test Coverage

Coverage 97.43%

Importance

Changes 0
Metric Value
eloc 310
dl 0
loc 700
ccs 379
cts 389
cp 0.9743
rs 2
c 0
b 0
f 0
wmc 112

46 Methods

Rating   Name   Duplication   Size   Complexity  
A getStructMethodParameter() 0 7 4
A getClassProperties() 0 5 3
A getModelAttributes() 0 3 1
A getStructMethodParametersValues() 0 7 2
A addStructMethodConstructBodyForAttribute() 0 5 2
A getStructMethodParameterType() 0 3 1
A fillClassMethods() 0 6 1
A getConstantAnnotationBlock() 0 2 1
A getPropertyAnnotationBlock() 0 13 3
A getClassConstants() 0 2 1
A addStructMethodAddTo() 0 10 2
A addStructMethodConstruct() 0 6 1
A addStructMethodConstructBody() 0 10 3
A addStructMethodsSetAndGet() 0 9 2
A addStructPropertiesToAnnotationBlockParams() 0 6 2
A getModel() 0 3 1
A addStructMethodsSetAndGetAnnotationBlockFromScalar() 0 11 3
A addStructPropertiesToAnnotationBlockUses() 0 6 2
A getStructMethodsValidateUnionAnnotationBlock() 0 9 1
A getStructMethodsAddToAnnotationBlock() 0 20 3
A addStructMethodAddToBody() 0 15 3
A addStructMethodGet() 0 11 2
A getStructMethodsValidateChoiceAnnotationBlock() 0 9 1
A addStructMethodGetBody() 0 3 1
A getStructMethodSetStateAnnotationBlock() 0 9 1
A addStructMethodSetBodyReturn() 0 4 1
A addStructMethodSetState() 0 8 1
A addStructMethodSet() 0 8 1
A addStructMethodsGetAnnotationBlockFromXmlAttribute() 0 8 2
A addStructMethodGetBodyReturn() 0 20 6
A getStructMethodsValidateLengthAnnotationBlock() 0 10 1
A addStructMethodSetBody() 0 7 2
C getStructMethodAnnotationBlock() 0 37 12
A getStructMethodsValidateArrayAnnotationBlock() 0 8 1
A getMethodAnnotationBlock() 0 3 1
B addStructMethodsSetAndGetAnnotationBlockFromStructAttribute() 0 41 11
A addStructPropertiesToAnnotationBlock() 0 3 1
A addStructMethodsGetAnnotationBlock() 0 4 1
A getStructMethodGetParameters() 0 7 2
A getStructMethodConstructAnnotationBlock() 0 7 1
A getStructMethodSetBodyAssignment() 0 16 4
A addStructMethodSetBodyAssignment() 0 15 4
A setModel() 0 6 2
A applyRules() 0 5 2
B getStructMethodsSetAndGetAnnotationBlock() 0 38 8
A addStructMethodsSetAnnotationBlock() 0 4 1

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.

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