Completed
Push — master ( d5332d...5d1b86 )
by
unknown
42:10 queued 41:08
created

JsValidatorFactory::validator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Proengsoft\JsValidation;
4
5
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
6
use Illuminate\Support\Arr;
7
use Illuminate\Validation\Validator;
8
use Proengsoft\JsValidation\Javascript\JavascriptValidator;
9
use Proengsoft\JsValidation\Javascript\MessageParser;
10
use Proengsoft\JsValidation\Javascript\RuleParser;
11
use Proengsoft\JsValidation\Javascript\ValidatorHandler;
12
use Proengsoft\JsValidation\Support\DelegatedValidator;
13
use Proengsoft\JsValidation\Support\ValidationRuleParserProxy;
14
15
class JsValidatorFactory
16
{
17
    /**
18
     * The application instance.
19
     *
20
     * @var \Illuminate\Container\Container
21
     */
22
    protected $app;
23
24
    /**
25
     * Configuration options.
26
     *
27
     * @var array
28
     */
29
    protected $options;
30
31
    /**
32
     * Create a new Validator factory instance.
33
     *
34
     * @param \Illuminate\Container\Container $app
35
     * @param array $options
36
     */
37 84
    public function __construct($app, array $options = [])
38
    {
39 84
        $this->app = $app;
40 84
        $this->setOptions($options);
41 84
    }
42
43
    /**
44
     * @param $options
45
     * @return void
46
     */
47 84
    protected function setOptions($options)
48
    {
49 84
        $options['disable_remote_validation'] = empty($options['disable_remote_validation']) ? false : $options['disable_remote_validation'];
50 84
        $options['view'] = empty($options['view']) ? 'jsvalidation:bootstrap' : $options['view'];
51 84
        $options['form_selector'] = empty($options['form_selector']) ? 'form' : $options['form_selector'];
52
53 84
        $this->options = $options;
54 84
    }
55
56
    /**
57
     * Creates JsValidator instance based on rules and message arrays.
58
     *
59
     * @param array $rules
60
     * @param array $messages
61
     * @param array $customAttributes
62
     * @param null|string $selector
63
     * @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
64
     */
65 48
    public function make(array $rules, array $messages = [], array $customAttributes = [], $selector = null)
66
    {
67 48
        $validator = $this->getValidatorInstance($rules, $messages, $customAttributes);
68
69 48
        return $this->validator($validator, $selector);
70
    }
71
72
    /**
73
     * Get the validator instance for the request.
74
     *
75
     * @param array $rules
76
     * @param array $messages
77
     * @param array $customAttributes
78
     * @return \Illuminate\Validation\Validator
79
     */
80 72
    protected function getValidatorInstance(array $rules, array $messages = [], array $customAttributes = [])
81
    {
82 72
        $factory = $this->app->make(ValidationFactory::class);
83
84 72
        $data = $this->getValidationData($rules, $customAttributes);
85 72
        $validator = $factory->make($data, $rules, $messages, $customAttributes);
86 72
        $validator->addCustomAttributes($customAttributes);
87
88 72
        return $validator;
89
    }
90
91
    /**
92
     * Gets fake data when validator has wildcard rules.
93
     *
94
     * @param array $rules
95
     * @return array
96
     */
97 72
    protected function getValidationData(array $rules, array $customAttributes = [])
98
    {
99
        $attributes = array_filter(array_keys($rules), function ($attribute) {
100 48
            return $attribute !== '' && mb_strpos($attribute, '*') !== false;
101 72
        });
102
103 72
        $attributes = array_merge(array_keys($customAttributes), $attributes);
104
        $data = array_reduce($attributes, function ($data, $attribute) {
105 24
            Arr::set($data, $attribute, true);
106
107 24
            return $data;
108 72
        }, []);
109
110 72
        return $data;
111
    }
112
113
    /**
114
     * Creates JsValidator instance based on FormRequest.
115
     *
116
     * @param $formRequest
117
     * @param null $selector
118
     * @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
119
     *
120
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
121
     */
122 24
    public function formRequest($formRequest, $selector = null)
123
    {
124 24
        if (! is_object($formRequest)) {
125 12
            $formRequest = $this->createFormRequest($formRequest);
126
        }
127
128 24
        $rules = method_exists($formRequest, 'rules') ? $formRequest->rules() : [];
129
130 24
        $validator = $this->getValidatorInstance($rules, $formRequest->messages(), $formRequest->attributes());
131
132 24
        $jsValidator = $this->validator($validator, $selector);
133
        
134 24
        if (method_exists($formRequest, 'withJsValidator')) {
135
            $formRequest->withJsValidator($jsValidator);
136
        }
137
        
138 24
        return $jsValidator;
139
    }
140
141
    /**
142
     * @param string|array $class
143
     * @return array
144
     */
145 12
    protected function parseFormRequestName($class)
146
    {
147 12
        $params = [];
148 12
        if (is_array($class)) {
149 12
            $params = empty($class[1]) ? $params : $class[1];
150 12
            $class = $class[0];
151
        }
152
153 12
        return [$class, $params];
154
    }
155
156
    /**
157
     * Creates and initializes an Form Request instance.
158
     *
159
     * @param string $class
160
     * @return \Illuminate\Foundation\Http\FormRequest
161
     *
162
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
163
     */
164 12
    protected function createFormRequest($class)
165
    {
166
        /*
167
         * @var $formRequest \Illuminate\Foundation\Http\FormRequest
168
         * @var $request Request
169
         */
170 12
        list($class, $params) = $this->parseFormRequestName($class);
171
172 12
        $request = $this->app->__get('request');
173 12
        $formRequest = $this->app->build($class, $params);
0 ignored issues
show
Unused Code introduced by
The call to Container::build() has too many arguments starting with $params.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
174
175 12
        if ($session = $request->getSession()) {
176 12
            $formRequest->setLaravelSession($session);
177
        }
178 12
        $formRequest->setUserResolver($request->getUserResolver());
179 12
        $formRequest->setRouteResolver($request->getRouteResolver());
180 12
        $formRequest->setContainer($this->app);
181 12
        $formRequest->query = $request->query;
182
183 12
        return $formRequest;
184
    }
185
186
    /**
187
     * Creates JsValidator instance based on Validator.
188
     *
189
     * @param \Illuminate\Validation\Validator $validator
190
     * @param null|string $selector
191
     * @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
192
     */
193 72
    public function validator(Validator $validator, $selector = null)
194
    {
195 72
        return $this->jsValidator($validator, $selector);
196
    }
197
198
    /**
199
     * Creates JsValidator instance based on Validator.
200
     *
201
     * @param \Illuminate\Validation\Validator $validator
202
     * @param null|string $selector
203
     * @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
204
     */
205 72
    protected function jsValidator(Validator $validator, $selector = null)
206
    {
207 72
        $remote = ! $this->options['disable_remote_validation'];
208 72
        $view = $this->options['view'];
209 72
        $selector = is_null($selector) ? $this->options['form_selector'] : $selector;
210
211 72
        $delegated = new DelegatedValidator($validator, new ValidationRuleParserProxy($validator->getData()));
212 72
        $rules = new RuleParser($delegated, $this->getSessionToken());
213 72
        $messages = new MessageParser($delegated, isset($this->options['escape']) ? $this->options['escape'] : false);
214
215 72
        $jsValidator = new ValidatorHandler($rules, $messages);
216
217 72
        $manager = new JavascriptValidator($jsValidator, compact('view', 'selector', 'remote'));
218
219 72
        return $manager;
220
    }
221
222
    /**
223
     * Get and encrypt token from session store.
224
     *
225
     * @return null|string
226
     */
227 72
    protected function getSessionToken()
228
    {
229 72
        $token = null;
230 72
        if ($session = $this->app->__get('session')) {
231 12
            $token = $session->token();
232
        }
233
234 72
        if ($encrypter = $this->app->__get('encrypter')) {
235 12
            $token = $encrypter->encrypt($token);
236
        }
237
238 72
        return $token;
239
    }
240
}
241