Completed
Branch feature/conditional-validation... (02769e)
by Albert
34:59 queued 25:31
created

ValidatorHandler   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 5
Bugs 2 Features 0
Metric Value
wmc 18
c 5
b 2
f 0
lcom 1
cbo 4
dl 0
loc 162
ccs 48
cts 48
cp 1
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A setDelegatedValidator() 0 6 1
A isValidatable() 0 4 3
A generateJavascriptValidations() 0 15 3
A jsConvertRules() 0 17 3
A jsValidationEnabled() 0 4 1
A validationData() 0 10 1
A sometimes() 0 11 3
A isConditionalRule() 0 5 2
1
<?php
2
3
namespace Proengsoft\JsValidation\Javascript;
4
5
use Illuminate\Validation\Validator;
6
use Proengsoft\JsValidation\Support\DelegatedValidator;
7
use Proengsoft\JsValidation\Support\UseDelegatedValidatorTrait;
8
9
class ValidatorHandler
10
{
11
    use UseDelegatedValidatorTrait;
12
13
    /**
14
     * Rule used to disable validations.
15
     *
16
     * @const string
17
     */
18
    const JSVALIDATION_DISABLE = 'NoJsValidation';
19
20
    /**
21
     * @var RuleParser
22
     */
23
    protected $rules;
24
    /**
25
     * @var MessageParser
26
     */
27
    protected $messages;
28
29
    protected $conditional = [];
30
31
    /**
32
     * Create a new JsValidation instance.
33
     *
34
     * @param RuleParser $rules
35
     * @param MessageParser $messages
36
     */
37 7
    public function __construct(RuleParser $rules, MessageParser $messages)
38
    {
39 7
        $this->rules = $rules;
40 7
        $this->messages = $messages;
41 7
        $this->validator = $rules->getDelegatedValidator();
42 7
    }
43
44
    /**
45
     * Sets delegated Validator instance.
46
     *
47
     * @param \Proengsoft\JsValidation\Support\DelegatedValidator $validator
48
     */
49 3
    public function setDelegatedValidator(DelegatedValidator $validator)
50
    {
51 3
        $this->validator = $validator;
52 3
        $this->rules->setDelegatedValidator($validator);
53 3
        $this->messages->setDelegatedValidator($validator);
54 3
    }
55
56 3
    protected function generateJavascriptValidations($includeRemote = true)
57
    {
58 3
        $jsValidations = array();
59
60 3
        foreach ($this->validator->getRules() as $attribute => $rules) {
61 3
            if (! $this->jsValidationEnabled($attribute)) {
62 1
                continue;
63
            }
64
65 2
            $newRules = $this->jsConvertRules($attribute, $rules, $includeRemote);
66 2
            $jsValidations = array_merge($jsValidations, $newRules);
67
        }
68
69 3
        return $jsValidations;
70
    }
71
72
    /**
73
     * Make Laravel Validations compatible with JQuery Validation Plugin.
74
     *
75
     * @param $attribute
76
     * @param $rules
77
     * @param $includeRemote
78
     *
79
     * @return array
80
     */
81 2
    protected function jsConvertRules($attribute, $rules, $includeRemote)
82
    {
83 2
        $jsRules = [];
84 2
        foreach ($rules as $rawRule) {
85 2
            $forceRemote = $this->isConditionalRule($attribute, $rawRule);
86 2
            list($rule, $parameters) = $this->validator->parseRule($rawRule);
87 2
            list($jsAttribute, $jsRule, $jsParams) = $this->rules->getRule($attribute, $rule, $parameters, $forceRemote);
88 2
            if ($this->isValidatable($jsRule, $includeRemote)) {
89 2
                $jsRules[$jsAttribute][$jsRule][] = array($rule, $jsParams,
90 2
                    $this->messages->getMessage($attribute, $rule, $parameters),
91 2
                    $this->validator->isImplicit($rule),
92
                );
93
            }
94
        }
95
96 2
        return $jsRules;
97
    }
98
99
    /**
100
     * Check if rule should be validated with javascript.
101
     *
102
     * @param $jsRule
103
     * @param $includeRemote
104
     * @return bool
105
     */
106 2
    protected function isValidatable($jsRule, $includeRemote)
107
    {
108 2
        return $jsRule && ($includeRemote || $jsRule !== RuleParser::REMOTE_RULE);
109
    }
110
111
    /**
112
     * Check if JS Validation is disabled for attribute.
113
     *
114
     * @param $attribute
115
     *
116
     * @return bool
117
     */
118 3
    public function jsValidationEnabled($attribute)
119
    {
120 3
        return ! $this->validator->hasRule($attribute, self::JSVALIDATION_DISABLE);
121
    }
122
123
    /**
124
     * Returns view data to render javascript.
125
     *
126
     * @param bool $remote
127
     * @return array
128
     */
129 3
    public function validationData($remote = true)
130
    {
131 3
        $jsMessages = array();
132 3
        $jsValidations = $this->generateJavascriptValidations($remote);
133
134
        return [
135 3
            'rules' => $jsValidations,
136 3
            'messages' => $jsMessages,
137
        ];
138
    }
139
140
    /**
141
     * Validate Conditional Validations using Ajax in specified fields.
142
     *
143
     * @param  string|array  $attribute
144
     * @param  string|array  $rules
145
     */
146
    public function sometimes($attribute, $rules = [])
147
    {
148 1
        $this->validator->sometimes($attribute, $rules, function () {
149
            return true;
150 1
        });
151 1
        foreach ((array) $attribute as $key) {
152 1
            $current = isset($this->conditional[$key]) ? $this->conditional[$key] : [];
153 1
            $merge = head($this->validator->explodeRules([$rules]));
154 1
            $this->conditional[$key] = array_merge($current, $merge);
155
        }
156 1
    }
157
158
    /**
159
     * Determine if rule is passed with sometimes.
160
     *
161
     * @param $attribute
162
     * @param $rule
163
     * @return bool
164
     */
165 2
    protected function isConditionalRule($attribute, $rule)
166
    {
167 2
        return isset($this->conditional[$attribute]) &&
168 2
            in_array($rule, $this->conditional[$attribute]);
169
    }
170
}
171