Completed
Pull Request — master (#348)
by
unknown
13:10
created

JsValidatorFactory::formRequest()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 6
cts 6
cp 1
rs 9.8666
cc 3
nc 4
nop 2
crap 3
1
<?php
2
3
    namespace Isrenato\JsValidation;
4
5
    use Illuminate\Contracts\Validation\Factory as ValidationFactory;
6
    use Illuminate\Support\Arr;
7
    use Illuminate\Validation\Validator;
8
    use Isrenato\JsValidation\Javascript\JavascriptValidator;
9
    use Isrenato\JsValidation\Javascript\MessageParser;
10
    use Isrenato\JsValidation\Javascript\RuleParser;
11
    use Isrenato\JsValidation\Javascript\ValidatorHandler;
12
    use Isrenato\JsValidation\Support\DelegatedValidator;
13
    use Isrenato\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 84
         */
37
        public function __construct($app, array $options = [])
38 84
        {
39 84
            $this->app = $app;
40 84
            $this->setOptions($options);
41
        }
42 84
43
        /**
44 84
         * @param $options
45 84
         *
46 84
         * @return void
47
         */
48 84
        protected function setOptions($options)
49 84
        {
50
            $options['disable_remote_validation'] = empty($options['disable_remote_validation']) ? false : $options['disable_remote_validation'];
51
            $options['view']                      = empty($options['view']) ? 'jsvalidation:bootstrap' : $options['view'];
52
            $options['form_selector']             = empty($options['form_selector']) ? 'form' : $options['form_selector'];
53
54
            $this->options = $options;
55
        }
56
57
        /**
58
         * Creates JsValidator instance based on rules and message arrays.
59
         *
60
         * @param array       $rules
61 48
         * @param array       $messages
62
         * @param array       $customAttributes
63 48
         * @param null|string $selector
64
         *
65 48
         * @return \Isrenato\JsValidation\Javascript\JavascriptValidator
66
         */
67
        public function make(array $rules, array $messages = [], array $customAttributes = [], $selector = null)
68
        {
69
            $validator = $this->getValidatorInstance($rules, $messages, $customAttributes);           
70
            return str_replace('[#]', '[*]', $this->validator($validator, $selector)->render());
71
        }
72
73
        /**
74
         * Get the validator instance for the request.
75
         *
76 72
         * @param array $rules
77
         * @param array $messages
78 72
         * @param array $customAttributes
79
         *
80 72
         * @return \Illuminate\Validation\Validator
81 72
         */
82 72
        protected function getValidatorInstance(array $rules, array $messages = [], array $customAttributes = [])
83
        {
84 72
            $factory = $this->app->make(ValidationFactory::class);
85
86
            $data      = $this->getValidationData($rules, $customAttributes);
87
            $validator = $factory->make($data, $rules, $messages, $customAttributes);
88
            $validator->addCustomAttributes($customAttributes);
89
90
            return $validator;
91
        }
92
93 72
        /**
94
         * Gets fake data when validator has wildcard rules.
95
         *
96 48
         * @param array $rules
97 72
         *
98
         * @return array
99 72
         */
100 72
        protected function getValidationData(array $rules, array $customAttributes = [])
101 24
        {
102
            $attributes = array_filter(array_keys($rules), function ($attribute) {
103 24
                return $attribute !== '' && mb_strpos($attribute, '*') !== false;
104 72
            });
105
106 72
            $attributes = array_merge(array_keys($customAttributes), $attributes);
107
            $attributes = str_replace('*', '#', $attributes);
108
            $data       = array_reduce($attributes, function ($data, $attribute) {
109
                Arr::set($data, $attribute, true);
110
111
                return $data;
112
            }, []);
113
114
            return $data;
115
        }
116
117
        /**
118 24
         * Creates JsValidator instance based on FormRequest.
119
         *
120 24
         * @param      $formRequest
121 12
         * @param null $selector
122 8
         *
123
         * @return \Isrenato\JsValidation\Javascript\JavascriptValidator
124 24
         *
125
         * @throws \Illuminate\Contracts\Container\BindingResolutionException
126 24
         */
127
        public function formRequest($formRequest, $selector = null)
128 24
        {
129
            if (!is_object($formRequest)) {
130
                $formRequest = $this->createFormRequest($formRequest);
131 12
            }
132
133 12
            $rules = method_exists($formRequest, 'rules') ? $formRequest->rules() : [];
134 12
135 12
            $validator = $this->getValidatorInstance($rules, $formRequest->messages(), $formRequest->attributes());
136 12
137 8
            return $this->validator($validator, $selector);
138
        }
139 12
140
        /**
141
         * @param string|array $class
142
         *
143
         * @return array
144
         */
145
        protected function parseFormRequestName($class)
146
        {
147
            $params = [];
148 12
            if (is_array($class)) {
149
                $params = empty($class[1]) ? $params : $class[1];
150
                $class  = $class[0];
151
            }
152
153
            return [$class, $params];
154 12
        }
155
156 12
        /**
157 12
         * Creates and initializes an Form Request instance.
158
         *
159 12
         * @param string $class
160 12
         *
161 8
         * @return \Illuminate\Foundation\Http\FormRequest
162 12
         *
163 12
         * @throws \Illuminate\Contracts\Container\BindingResolutionException
164 12
         */
165 12
        protected function createFormRequest($class)
166
        {
167 12
            /*
168
             * @var $formRequest \Illuminate\Foundation\Http\FormRequest
169
             * @var $request Request
170
             */
171
            list($class, $params) = $this->parseFormRequestName($class);
172
173
            $request     = $this->app->__get('request');
174
            $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...
175
176
            if ($session = $request->getSession()) {
177
                $formRequest->setLaravelSession($session);
178 72
            }
179
            $formRequest->setUserResolver($request->getUserResolver());
180 72
            $formRequest->setRouteResolver($request->getRouteResolver());
181
            $formRequest->setContainer($this->app);
182
            $formRequest->query = $request->query;
183
184
            return $formRequest;
185
        }
186
187
        /**
188
         * Creates JsValidator instance based on Validator.
189
         *
190
         * @param \Illuminate\Validation\Validator $validator
191 72
         * @param null|string                      $selector
192
         *
193 72
         * @return \Isrenato\JsValidation\Javascript\JavascriptValidator
194 72
         */
195 72
        public function validator(Validator $validator, $selector = null)
196
        {
197 72
            return $this->jsValidator($validator, $selector);
198 72
        }
199 72
200
        /**
201 72
         * Creates JsValidator instance based on Validator.
202
         *
203 72
         * @param \Illuminate\Validation\Validator $validator
204
         * @param null|string                      $selector
205 72
         *
206
         * @return \Proengsoft\JsValidation\Javascript\JavascriptValidator
207
         */
208
        protected function jsValidator(Validator $validator, $selector = null)
209
        {
210
            $remote   = !$this->options['disable_remote_validation'];
211
            $view     = $this->options['view'];
212
            $selector = is_null($selector) ? $this->options['form_selector'] : $selector;
213 72
214
            $delegated = new DelegatedValidator($validator, new ValidationRuleParserProxy());
215 72
            $rules     = new RuleParser($delegated, $this->getSessionToken());
216 72
            $messages  = new MessageParser($delegated);
217 12
218 8
            $jsValidator = new ValidatorHandler($rules, $messages);
219
220 72
            $manager = new JavascriptValidator($jsValidator, compact('view', 'selector', 'remote'));
221 12
222 8
            return $manager;
223
        }
224 72
225
        /**
226
         * Get and encrypt token from session store.
227
         *
228
         * @return null|string
229
         */
230
        protected function getSessionToken()
231
        {
232
            $token = null;
233
            if ($session = $this->app->__get('session')) {
234
                $token = $session->token();
235
            }
236
237
            if ($encrypter = $this->app->__get('encrypter')) {
238
                $token = $encrypter->encrypt($token);
239
            }
240
241
            return $token;
242
        }
243
    }
244