Completed
Push — feature/issue-165 ( 83f642...d66719 )
by Mikaël
23:02 queued 18s
created

UnionRule::name()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace WsdlToPhp\PackageGenerator\File\Validation;
4
5
use WsdlToPhp\PackageGenerator\Model\StructAttribute;
6
use WsdlToPhp\PhpGenerator\Element\PhpFunctionParameter;
7
use WsdlToPhp\PhpGenerator\Element\PhpMethod;
8
9
class UnionRule extends AbstractRule
10
{
11
12
    /**
13
     * @return string
14
     */
15 6
    public function name()
16
    {
17 6
        return 'union';
18
    }
19
20
    /**
21
     * @param string $parameterName
22
     * @param mixed $value
23
     * @param bool $itemType
24
     * @return string
25
     */
26 6
    public function testConditions($parameterName, $value, $itemType = false)
27
    {
28 6
        if (is_array($value) && 0 < count($value)) {
29 6
            $this->addValidationMethod($parameterName, $value);
30 6
            return sprintf('\'\' !== ($message = self::%s($%s))', $this->getValidationMethodName($parameterName), $parameterName);
31
        }
32
    }
33
34
    /**
35
     * @param string $parameterName
36
     * @param mixed $value
37
     * @param bool $itemType
38
     * @return string
39
     */
40 6
    public function exceptionMessageOnTestFailure($parameterName, $value, $itemType = false)
41
    {
42 6
        return '$message';
43
    }
44
45
    /**
46
     * @param $parameterName
47
     * @param mixed $unionValues
48
     */
49 6
    protected function addValidationMethod($parameterName, array $unionValues)
50
    {
51 6
        $method = new PhpMethod('temp');
52 6
        $rules = clone $this->getRules();
53 6
        $rules->setMethod($method);
54
55
        // gather validation rules
56 6
        foreach ($unionValues as $unionValue) {
57 6
            $rules->setAttribute(new StructAttribute($this->getGenerator(), 'any', $unionValue));
58 6
            $rules->applyRules('value');
59 3
        }
60
61
        // adapt content, remove duplicated rules
62
        // duplicated rules is base don the fact that validation rules are composed by 4 lines so we check existing rule every 4-line block of text
63 6
        $exceptions = 0;
64 6
        $exceptionsTests = [];
65 6
        $exceptionsArray = [];
66 6
        $children = [];
67 6
        $methodChildren = $method->getChildren();
68 6
        $chilrenCount = count($methodChildren);
69 6
        $existingValidationRules = [];
70 6
        for ($i = 0;$i < $chilrenCount;$i += 4) {
71 6
            $validationRules = array_slice($methodChildren, ((int) $i / 4) * 4, 4);
72 6
            if (!in_array($validationRules, $existingValidationRules)) {
73 6
                foreach ($validationRules as $validationRule) {
74 6
                    if (is_string($validationRule) && false !== strpos($validationRule, 'throw new')) {
75 6
                        $exceptionName = sprintf('$exception%d', $exceptions++);
76 6
                        $validationRule = str_replace('throw new', sprintf('%s = new', $exceptionName), $validationRule);
77 6
                        $exceptionsTests[] = sprintf('isset(%s)', $exceptionName);
78 6
                        $exceptionsArray[] = $exceptionName;
79 3
                    }
80 6
                    $children[] = $validationRule;
81 3
                }
82 3
            }
83 6
            $existingValidationRules[] = $validationRules;
84 3
        }
85
86
        // populate final validation method
87 6
        $method = new PhpMethod($this->getValidationMethodName($parameterName), [
88 6
            new PhpFunctionParameter('value', PhpFunctionParameter::NO_VALUE),
89 6
        ], PhpMethod::ACCESS_PUBLIC, false, true);
90 6
        $method->addChild('$message = \'\';');
91 6
        array_walk($children, [
92 6
            $method,
93 6
            'addChild',
94 3
        ]);
95
        $method
96 6
            ->addChild(sprintf('if (%s) {', implode(' && ', $exceptionsTests)))
97 6
            ->addChild($method->getIndentedString(sprintf('$message = sprintf("The value %%s does not match any of the union rules: %s. See following errors:\n%%s", var_export($value, true), implode("\n", array_map(function(\InvalidArgumentException $e) { return sprintf(\' - %%s\', $e->getMessage()); }, [%s])));', implode(', ', $unionValues), implode(', ', $exceptionsArray)), 1))
98 6
            ->addChild('}')
99 6
            ->addChild(sprintf('unset(%s);', implode(', ', $exceptionsArray)))
100 6
            ->addChild('return $message;');
101 6
        $this->getMethods()->add($method);
102 6
    }
103
104
    /**
105
     * @param string $parameterName
106
     * @return string
107
     */
108 6
    protected function getValidationMethodName($parameterName)
109
    {
110 6
        return sprintf('validate%sForUnionConstraintsFrom%s', ucfirst($parameterName), ucFirst($this->getMethod()->getName()));
111
    }
112
}
113