Completed
Push — master ( 12306b...c95df9 )
by Albert
04:09 queued 02:40
created

JsValidatorFactory::jsValidator()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

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