Completed
Push — master ( 7e48c0...dd127d )
by Albert
07:23
created

Validator::validate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1.0046

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 5
cts 6
cp 0.8333
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
crap 1.0046
1
<?php
2
3
namespace Proengsoft\JsValidation\Remote;
4
5
use Illuminate\Http\JsonResponse;
6
use Proengsoft\JsValidation\Support\RuleListTrait;
7
use Illuminate\Http\Exception\HttpResponseException;
8
use Illuminate\Validation\Validator as BaseValidator;
9
use Proengsoft\JsValidation\Support\AccessProtectedTrait;
10
11
/**
12
 * Class RemoteValidator.
13
 */
14
class Validator
15
{
16
    use AccessProtectedTrait, RuleListTrait;
17
18
    /**
19
     * Validator extension name.
20
     */
21
    const EXTENSION_NAME = 'jsvalidation';
22
23
    /**
24
     * @var \Illuminate\Validation\Validator
25
     */
26
    protected $validator;
27
28
    /**
29
     * RemoteValidator constructor.
30
     *
31
     * @param \Illuminate\Validation\Validator $validator
32
     */
33 60
    public function __construct(BaseValidator $validator)
34
    {
35 60
        $this->validator = $validator;
36 60
    }
37
38
    /**
39
     * Validate request.
40
     *
41
     * @param $field
42
     * @param $parameters
43
     */
44 60
    public function validate($field, $parameters = [])
45
    {
46 60
        $attribute = $this->parseAttributeName($field);
47 60
        $validationParams = $this->parseParameters($parameters);
48 60
        $validationResult = $this->validateJsRemoteRequest($attribute, $validationParams);
49
50 60
        $this->throwValidationException($validationResult, $this->validator);
51
    }
52
53
    /**
54
     * Throw the failed validation exception.
55
     *
56
     * @param  mixed $result
57
     * @param  \Illuminate\Validation\Validator  $validator
58
     * @return void
59
     *
60
     * @throws \Illuminate\Validation\ValidationException|\Illuminate\Http\Exception\HttpResponseException
61
     */
62 60
    protected function throwValidationException($result, $validator)
63
    {
64 60
        $response = new JsonResponse($result, 200);
65
66 60
        if ($result !== true && class_exists('\Illuminate\Validation\ValidationException')) {
67 10
            throw new \Illuminate\Validation\ValidationException($validator, $response);
68
        }
69 50
        throw new HttpResponseException($response);
70
    }
71
72
    /**
73
     *  Parse Validation input request data.
74
     *
75
     * @param $data
76
     * @return array
77
     */
78 60
    protected function parseAttributeName($data)
79
    {
80 60
        parse_str($data, $attrParts);
81 60
        $attrParts = is_null($attrParts) ? [] : $attrParts;
82 60
        $newAttr = array_keys(array_dot($attrParts));
83
84 60
        return array_pop($newAttr);
85
    }
86
87
    /**
88
     *  Parse Validation parameters.
89
     *
90
     * @param $parameters
91
     * @return array
92
     */
93 60
    protected function parseParameters($parameters)
94
    {
95 60
        $newParams = ['validate_all' => false];
96 60
        if (isset($parameters[0])) {
97 48
            $newParams['validate_all'] = ($parameters[0] === 'true') ? true : false;
98 32
        }
99
100 60
        return $newParams;
101
    }
102
103
    /**
104
     * Validate remote Javascript Validations.
105
     *
106
     * @param $attribute
107
     * @param array $parameters
108
     * @return array|bool
109
     */
110 60
    protected function validateJsRemoteRequest($attribute, $parameters)
111
    {
112 60
        $this->setRemoteValidation($attribute, $parameters['validate_all']);
113
114 60
        $validator = $this->validator;
115 60
        if ($validator->passes()) {
116 36
            return true;
117
        }
118
119 24
        return $validator->messages()->get($attribute);
120
    }
121
122
    /**
123
     * Sets data for validate remote rules.
124
     *
125
     * @param $attribute
126
     * @param bool $validateAll
127
     */
128 60
    protected function setRemoteValidation($attribute, $validateAll = false)
129
    {
130 60
        $validator = $this->validator;
131 60
        $rules = $validator->getRules();
132 60
        $rules = isset($rules[$attribute]) ? $rules[$attribute] : [];
133 60
        if (in_array('no_js_validation', $rules)) {
134 12
            $validator->setRules([$attribute => []]);
135
136 12
            return;
137
        }
138 48
        if (! $validateAll) {
139 36
            $rules = $this->purgeNonRemoteRules($rules, $validator);
140 24
        }
141 48
        $validator->setRules([$attribute => $rules]);
142 48
    }
143
144
    /**
145
     * Remove rules that should not be validated remotely.
146
     *
147
     * @param $rules
148
     * @param BaseValidator $validator
149
     * @return mixed
150
     */
151 36
    protected function purgeNonRemoteRules($rules, $validator)
152
    {
153 36
        $protectedValidator = $this->createProtectedCaller($validator);
154
155 36
        foreach ($rules as $i => $rule) {
156 36
            $parsedRule = call_user_func($protectedValidator, 'parseRule', [$rule]);
157 36
            if (! $this->isRemoteRule($parsedRule[0])) {
158 36
                unset($rules[$i]);
159 24
            }
160 24
        }
161
162 36
        return $rules;
163
    }
164
}
165