Passed
Push — develop ( cda1c3...d73d2f )
by Mikaël
10:01
created

AbstractRule::getAttribute()   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
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
20 156
    public function __construct(Rules $rules)
21
    {
22 156
        $this->rules = $rules;
23
    }
24
25 154
    final public function applyRule(string $parameterName, $value, bool $itemType = false): void
26
    {
27 154
        $test = $this->testConditions($parameterName, $value, $itemType);
28 154
        if (!empty($test)) {
29 154
            $message = $this->exceptionMessageOnTestFailure($parameterName, $value, $itemType);
30 154
            $this
31 154
                ->getMethod()
32 154
                ->addChild($this->validationRuleComment($value))
33 154
                ->addChild(sprintf('if (%s) {', $test))
34 154
                ->addChild($this->getMethod()->getIndentedString(sprintf('throw new InvalidArgumentException(%s, __LINE__);', $message), 1))
35 154
                ->addChild('}')
36 154
            ;
37 154
            unset($message);
38 154
            Rules::ruleHasBeenAppliedToAttribute($this, $value, $this->getAttribute());
39
        }
40 154
        unset($test);
41
    }
42
43 154
    final public function validationRuleComment($value): string
44
    {
45 154
        return sprintf(
46 154
            '// %s %s%s',
47 154
            self::VALIDATION_RULE_COMMENT_SENTENCE,
48 154
            $this->name(),
49 154
            is_array($value) ? sprintf('(%s)', implode(', ', array_unique($value))) : (empty($value) ? '' : sprintf('(%s)', $value))
50 154
        );
51
    }
52
53
    abstract public function name(): string;
54
55
    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
59 68
    public function getRules(): Rules
60
    {
61 68
        return $this->rules;
62
    }
63
64 154
    public function getMethod(): PhpMethod
65
    {
66 154
        return $this->rules->getMethod();
67
    }
68
69 72
    public function getMethods(): MethodContainer
70
    {
71 72
        return $this->rules->getMethods();
72
    }
73
74 86
    public function getFile(): AbstractModelFile
75
    {
76 86
        return $this->rules->getFile();
77
    }
78
79 154
    public function getAttribute(): StructAttributeModel
80
    {
81 154
        return $this->rules->getAttribute();
82
    }
83
84 4
    public function getGenerator(): Generator
85
    {
86 4
        return $this->rules->getGenerator();
87
    }
88
89 14
    final protected function addArrayValidationMethod(string $parameterName, $value): void
90
    {
91 14
        $itemName = sprintf(
92 14
            '%s%sItem',
93 14
            lcfirst($this->getFile()->getModel()->getCleanName(false)),
94 14
            ucfirst($this->getAttribute()->getCleanName())
95 14
        );
96 14
        $method = new PhpMethod($this->getValidationMethodName($parameterName), [
97 14
            new PhpFunctionParameter('values', null, '?array'),
98 14
        ], AbstractModelFile::TYPE_STRING, PhpMethod::ACCESS_PUBLIC, false, true);
99
100 14
        $method
101 14
            ->addChild('$message = \'\';')
102 14
            ->addChild('$invalidValues = [];')
103 14
            ->addChild(sprintf('foreach (($values ?? []) as $%s) {', $itemName))
104 14
            ->addChild($method->getIndentedString($this->validationRuleComment($value), 1))
105 14
            ->addChild($method->getIndentedString(sprintf('if (%s) {', $this->testConditions($itemName, $value, true)), 1))
106 14
            ->addChild($method->getIndentedString(sprintf('$invalidValues[] = var_export($%s, true);', $itemName), 2))
107 14
            ->addChild($method->getIndentedString('}', 1))
108 14
            ->addChild('}')
109 14
            ->addChild('if (!empty($invalidValues)) {')
110 14
            ->addChild($method->getIndentedString(
111 14
                sprintf(
112 14
                    '$message = sprintf(\'%s\', implode(\', \', $invalidValues));',
113 14
                    addslashes($this->getArrayExceptionMessageOnTestFailure($value)),
114 14
                ),
115 14
                1
116 14
            ))
117 14
            ->addChild('}')
118 14
            ->addChild('unset($invalidValues);')
119 14
            ->addChild('')
120 14
            ->addChild('return $message;')
121 14
        ;
122 14
        $this->getMethods()->add($method);
123
    }
124
125
    protected function getArrayExceptionMessageOnTestFailure($value): string
126
    {
127
        return '';
128
    }
129
130 72
    final protected function getValidationMethodName(string $parameterName): string
131
    {
132 72
        return sprintf(
133 72
            'validate%sFor%sConstraintFrom%s',
134 72
            ucfirst($parameterName),
135 72
            ucfirst($this->name()),
136 72
            ucfirst($this->getMethod()->getName())
137 72
        );
138
    }
139
140 14
    final protected function getArrayErrorMessageVariableName(string $parameterName): string
141
    {
142 14
        return sprintf('$%s%sErrorMessage', $parameterName, ucfirst($this->name()));
143
    }
144
}
145