Passed
Push — master ( f0393b...d8ac0a )
by Mikaël
12:30 queued 13s
created

AbstractRule::addArrayValidationMethod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 34
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 26
nc 1
nop 2
dl 0
loc 34
ccs 0
cts 0
cp 0
crap 2
rs 9.504
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WsdlToPhp\PackageGenerator\File\Validation;
6
7
use WsdlToPhp\PackageGenerator\Container\PhpElement\Method as MethodContainer;
8
use WsdlToPhp\PackageGenerator\File\AbstractModelFile;
9
use WsdlToPhp\PackageGenerator\Generator\Generator;
10
use WsdlToPhp\PackageGenerator\Model\StructAttribute as StructAttributeModel;
11
use WsdlToPhp\PhpGenerator\Element\PhpFunctionParameter;
12
use WsdlToPhp\PhpGenerator\Element\PhpMethod;
13
14
abstract class AbstractRule
15
{
16
    public const VALIDATION_RULE_COMMENT_SENTENCE = 'validation for constraint:';
17
18
    protected Rules $rules;
19 148
20
    public function __construct(Rules $rules)
21 148
    {
22 148
        $this->rules = $rules;
23
    }
24 146
25
    final public function applyRule(string $parameterName, $value, bool $itemType = false): void
26 146
    {
27 146
        $test = $this->testConditions($parameterName, $value, $itemType);
28 146
        if (!empty($test)) {
29
            $message = $this->exceptionMessageOnTestFailure($parameterName, $value, $itemType);
30 146
            $this
31 146
                ->getMethod()
32 146
                ->addChild($this->validationRuleComment($value))
33 146
                ->addChild(sprintf('if (%s) {', $test))
34 146
                ->addChild($this->getMethod()->getIndentedString(sprintf('throw new InvalidArgumentException(%s, __LINE__);', $message), 1))
35
                ->addChild('}')
36 146
            ;
37 146
            unset($message);
38
            Rules::ruleHasBeenAppliedToAttribute($this, $value, $this->getAttribute());
39 146
        }
40 146
        unset($test);
41
    }
42 146
43
    final public function validationRuleComment($value): string
44 146
    {
45
        return sprintf(
46
            '// %s %s%s',
47
            self::VALIDATION_RULE_COMMENT_SENTENCE,
48
            $this->name(),
49
            is_array($value) ? sprintf('(%s)', implode(', ', array_unique($value))) : (empty($value) ? '' : sprintf('(%s)', $value))
50
        );
51
    }
52
53 60
    abstract public function name(): string;
54
55 60
    abstract public function testConditions(string $parameterName, $value, bool $itemType = false): string;
56
57
    abstract public function exceptionMessageOnTestFailure(string $parameterName, $value, bool $itemType = false): string;
58 146
59
    public function getRules(): Rules
60 146
    {
61
        return $this->rules;
62
    }
63 66
64
    public function getMethod(): PhpMethod
65 66
    {
66
        return $this->rules->getMethod();
67
    }
68 78
69
    public function getMethods(): MethodContainer
70 78
    {
71
        return $this->rules->getMethods();
72
    }
73 146
74
    public function getFile(): AbstractModelFile
75 146
    {
76
        return $this->rules->getFile();
77
    }
78 4
79
    public function getAttribute(): StructAttributeModel
80 4
    {
81
        return $this->rules->getAttribute();
82
    }
83
84
    public function getGenerator(): Generator
85
    {
86
        return $this->rules->getGenerator();
87
    }
88
89
    final protected function addArrayValidationMethod(string $parameterName, $value): void
90
    {
91
        $itemName = sprintf(
92
            '%s%sItem',
93
            lcfirst($this->getFile()->getModel()->getCleanName(false)),
94
            ucfirst($this->getAttribute()->getCleanName())
95
        );
96
        $method = new PhpMethod($this->getValidationMethodName($parameterName), [
97
            new PhpFunctionParameter('values', null, '?array'),
98
        ], AbstractModelFile::TYPE_STRING, PhpMethod::ACCESS_PUBLIC, false, true);
99
100
        $method
101
            ->addChild('$message = \'\';')
102
            ->addChild('$invalidValues = [];')
103
            ->addChild(sprintf('foreach (($values ?? []) as $%s) {', $itemName))
104
            ->addChild($method->getIndentedString($this->validationRuleComment($value), 1))
105
            ->addChild($method->getIndentedString(sprintf('if (%s) {', $this->testConditions($itemName, $value, true)), 1))
106
            ->addChild($method->getIndentedString(sprintf('$invalidValues[] = var_export($%s, true);', $itemName), 2))
107
            ->addChild($method->getIndentedString('}', 1))
108
            ->addChild('}')
109
            ->addChild('if (!empty($invalidValues)) {')
110
            ->addChild($method->getIndentedString(
111
                sprintf(
112
                    '$message = sprintf(\'%s\', implode(\', \', $invalidValues));',
113
                    addslashes($this->getArrayExceptionMessageOnTestFailure($value)),
114
                ),
115
                1
116
            ))
117
            ->addChild('}')
118
            ->addChild('unset($invalidValues);')
119
            ->addChild('')
120
            ->addChild('return $message;')
121
        ;
122
        $this->getMethods()->add($method);
123
    }
124
125
    protected function getArrayExceptionMessageOnTestFailure($value): string
126
    {
127
        return '';
128
    }
129
130
    final protected function getValidationMethodName(string $parameterName): string
131
    {
132
        return sprintf(
133
            'validate%sFor%sConstraintFrom%s',
134
            ucfirst($parameterName),
135
            ucfirst($this->name()),
136
            ucfirst($this->getMethod()->getName())
137
        );
138
    }
139
140
    final protected function getArrayErrorMessageVariableName(string $parameterName): string
141
    {
142
        return sprintf('$%s%sErrorMessage', $parameterName, ucfirst($this->name()));
143
    }
144
}
145