Completed
Push — master ( 97eb8d...d5332d )
by
unknown
59:42 queued 58:43
created

Validator   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 174
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 98.11%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 9
dl 0
loc 174
ccs 52
cts 53
cp 0.9811
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A throwValidationException() 0 10 3
A parseAttributeName() 0 8 2
A __construct() 0 5 1
A validate() 0 8 1
A parseParameters() 0 9 3
A validateJsRemoteRequest() 0 19 4
A setRemoteValidation() 0 15 4
A purgeNonRemoteRules() 0 13 3
1
<?php
2
3
namespace Proengsoft\JsValidation\Remote;
4
5
use Illuminate\Http\Exceptions\HttpResponseException;
6
use Illuminate\Http\JsonResponse;
7
use Illuminate\Support\Arr;
8
use Illuminate\Validation\ValidationException;
9
use Illuminate\Validation\ValidationRuleParser;
10
use Illuminate\Validation\Validator as BaseValidator;
11
use Proengsoft\JsValidation\Support\AccessProtectedTrait;
12
use Proengsoft\JsValidation\Support\RuleListTrait;
13
14
class Validator
15
{
16
    use AccessProtectedTrait;
17
    use RuleListTrait;
18
19
    /**
20
     * Validator extension name.
21
     */
22
    const EXTENSION_NAME = 'jsvalidation';
23
24
    /**
25
     * @var \Illuminate\Validation\Validator
26
     */
27
    protected $validator;
28
29
    /**
30
     * Whether to escape validation messages.
31
     *
32
     * @var bool
33
     */
34
    protected $escape;
35
36
    /**
37
     * RemoteValidator constructor.
38
     *
39
     * @param \Illuminate\Validation\Validator $validator
40
     * @param bool $escape
41
     */
42 72
    public function __construct(BaseValidator $validator, $escape = false)
43
    {
44 72
        $this->validator = $validator;
45 72
        $this->escape = $escape;
46 72
    }
47
48
    /**
49
     * Validate request.
50
     *
51
     * @param $field
52
     * @param $parameters
53
     * @return void
54
     *
55
     * @throws \Illuminate\Validation\ValidationException
56
     */
57 72
    public function validate($field, $parameters = [])
58
    {
59 72
        $attribute = $this->parseAttributeName($field);
60 72
        $validationParams = $this->parseParameters($parameters);
61 72
        $validationResult = $this->validateJsRemoteRequest($attribute, $validationParams);
62
63 72
        $this->throwValidationException($validationResult, $this->validator);
64
    }
65
66
    /**
67
     * Throw the failed validation exception.
68
     *
69
     * @param mixed $result
70
     * @param \Illuminate\Validation\Validator  $validator
71
     * @return void
72
     *
73
     * @throws \Illuminate\Validation\ValidationException|\Illuminate\Http\Exceptions\HttpResponseException
74
     */
75 72
    protected function throwValidationException($result, $validator)
76
    {
77 72
        $response = new JsonResponse($result, 200);
78
79 72
        if ($result !== true && class_exists(ValidationException::class)) {
80 36
            throw new ValidationException($validator, $response);
81
        }
82
83 36
        throw new HttpResponseException($response);
84
    }
85
86
    /**
87
     *  Parse Validation input request data.
88
     *
89
     * @param $data
90
     * @return array
91
     */
92 72
    protected function parseAttributeName($data)
93
    {
94 72
        parse_str($data, $attrParts);
95 72
        $attrParts = is_null($attrParts) ? [] : $attrParts;
96 72
        $newAttr = array_keys(Arr::dot($attrParts));
0 ignored issues
show
Documentation introduced by
$attrParts is of type array, but the function expects a object<Illuminate\Support\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
97
98 72
        return array_pop($newAttr);
99
    }
100
101
    /**
102
     *  Parse Validation parameters.
103
     *
104
     * @param $parameters
105
     * @return array
106
     */
107 72
    protected function parseParameters($parameters)
108
    {
109 72
        $newParams = ['validate_all' => false];
110 72
        if (isset($parameters[0])) {
111 60
            $newParams['validate_all'] = ($parameters[0] === 'true') ? true : false;
112
        }
113
114 72
        return $newParams;
115
    }
116
117
    /**
118
     * Validate remote Javascript Validations.
119
     *
120
     * @param $attribute
121
     * @param array $parameters
122
     * @return array|bool
123
     */
124 72
    protected function validateJsRemoteRequest($attribute, $parameters)
125
    {
126 72
        $this->setRemoteValidation($attribute, $parameters['validate_all']);
127
128 72
        $validator = $this->validator;
129 72
        if ($validator->passes()) {
130 36
            return true;
131
        }
132
133 36
        $messages = $validator->messages()->get($attribute);
134
135 36
        if ($this->escape) {
136 12
            foreach ($messages as $key => $value) {
137 12
                $messages[$key] = e($value);
138
            }
139
        }
140
141 36
        return $messages;
142
    }
143
144
    /**
145
     * Sets data for validate remote rules.
146
     *
147
     * @param $attribute
148
     * @param bool $validateAll
149
     * @return void
150
     */
151 72
    protected function setRemoteValidation($attribute, $validateAll = false)
152
    {
153 72
        $validator = $this->validator;
154 72
        $rules = $validator->getRules();
155 72
        $rules = isset($rules[$attribute]) ? $rules[$attribute] : [];
156 72
        if (in_array('no_js_validation', $rules)) {
157 12
            $validator->setRules([$attribute => []]);
158
159 12
            return;
160
        }
161 60
        if (! $validateAll) {
162 48
            $rules = $this->purgeNonRemoteRules($rules, $validator);
163
        }
164 60
        $validator->setRules([$attribute => $rules]);
165 60
    }
166
167
    /**
168
     * Remove rules that should not be validated remotely.
169
     *
170
     * @param $rules
171
     * @param BaseValidator $validator
172
     * @return mixed
173
     */
174 48
    protected function purgeNonRemoteRules($rules, $validator)
175
    {
176 48
        $protectedValidator = $this->createProtectedCaller($validator);
0 ignored issues
show
Unused Code introduced by
$protectedValidator is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
177
178 48
        foreach ($rules as $i => $rule) {
179 48
            $parsedRule = ValidationRuleParser::parse([$rule]);
180 48
            if (! $this->isRemoteRule($parsedRule[0])) {
181 48
                unset($rules[$i]);
182
            }
183
        }
184
185 48
        return $rules;
186
    }
187
}
188