Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.46% covered (success)
98.46%
64 / 65
92.31% covered (success)
92.31%
12 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractRule
98.46% covered (success)
98.46%
64 / 65
92.31% covered (success)
92.31%
12 / 13
16
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 applyRule
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
2
 validationRuleComment
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 name
n/a
0 / 0
n/a
0 / 0
0
 testConditions
n/a
0 / 0
n/a
0 / 0
0
 exceptionMessageOnTestFailure
n/a
0 / 0
n/a
0 / 0
0
 getRules
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMethod
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMethods
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFile
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getAttribute
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGenerator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addArrayValidationMethod
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
1 / 1
1
 getArrayExceptionMessageOnTestFailure
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getValidationMethodName
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getArrayErrorMessageVariableName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace WsdlToPhp\PackageGenerator\File\Validation;
6
7use WsdlToPhp\PackageGenerator\Container\PhpElement\Method as MethodContainer;
8use WsdlToPhp\PackageGenerator\File\AbstractModelFile;
9use WsdlToPhp\PackageGenerator\Generator\Generator;
10use WsdlToPhp\PackageGenerator\Model\StructAttribute as StructAttributeModel;
11use WsdlToPhp\PhpGenerator\Element\PhpFunctionParameter;
12use WsdlToPhp\PhpGenerator\Element\PhpMethod;
13
14abstract class AbstractRule
15{
16    public const VALIDATION_RULE_COMMENT_SENTENCE = 'validation for constraint:';
17
18    protected Rules $rules;
19
20    public function __construct(Rules $rules)
21    {
22        $this->rules = $rules;
23    }
24
25    final public function applyRule(string $parameterName, $value, bool $itemType = false): void
26    {
27        $test = $this->testConditions($parameterName, $value, $itemType);
28        if (!empty($test)) {
29            $message = $this->exceptionMessageOnTestFailure($parameterName, $value, $itemType);
30            $this
31                ->getMethod()
32                ->addChild($this->validationRuleComment($value))
33                ->addChild(sprintf('if (%s) {', $test))
34                ->addChild($this->getMethod()->getIndentedString(sprintf('throw new InvalidArgumentException(%s, __LINE__);', $message), 1))
35                ->addChild('}')
36            ;
37            unset($message);
38            Rules::ruleHasBeenAppliedToAttribute($this, $value, $this->getAttribute());
39        }
40        unset($test);
41    }
42
43    final public function validationRuleComment($value): string
44    {
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    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    public function getRules(): Rules
60    {
61        return $this->rules;
62    }
63
64    public function getMethod(): PhpMethod
65    {
66        return $this->rules->getMethod();
67    }
68
69    public function getMethods(): MethodContainer
70    {
71        return $this->rules->getMethods();
72    }
73
74    public function getFile(): AbstractModelFile
75    {
76        return $this->rules->getFile();
77    }
78
79    public function getAttribute(): StructAttributeModel
80    {
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}