1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
/**
|
4 |
|
|
* @file
|
5 |
81b16cc2
|
Assos Assos
|
* Provides validation functionality and hooks.
|
6 |
85ad3d82
|
Assos Assos
|
*/
|
7 |
|
|
|
8 |
|
|
/**
|
9 |
|
|
* Implements hook_webform_validation_validators().
|
10 |
|
|
*
|
11 |
76bdcd04
|
Assos Assos
|
* This function returns an array of validators, in the validator key => options
|
12 |
|
|
* array form. Possible options:
|
13 |
|
|
* - name (required): name of the validator.
|
14 |
|
|
* - component_types (required): defines which component types can be validated
|
15 |
|
|
* by this validator. Specify 'all' to allow all types.
|
16 |
|
|
* - negatable (optional): define whether the rule can be negated, meaning it
|
17 |
|
|
* will validate the inverse of the rule.
|
18 |
|
|
* - custom_error (optional): define whether a user can specify a custom error
|
19 |
|
|
* message upon creating the validation rule.
|
20 |
|
|
* - custom_data (optional): define whether custom data can be added to the
|
21 |
|
|
* validation rule.
|
22 |
|
|
* - min_components (optional): define the minimum number of components to be
|
23 |
|
|
* selected for creating a validation rule.
|
24 |
|
|
* - max_components (optional): define the maximum number of components to be
|
25 |
|
|
* selected for creating a validation rule.
|
26 |
|
|
* - description (optional): provide a descriptive explanation about the
|
27 |
|
|
* validator.
|
28 |
85ad3d82
|
Assos Assos
|
*/
|
29 |
|
|
function webform_validation_webform_validation_validators() {
|
30 |
|
|
$validators = array(
|
31 |
|
|
'numeric' => array(
|
32 |
|
|
'name' => t('Numeric values'),
|
33 |
|
|
'component_types' => array(
|
34 |
5c451ca3
|
Assos Assos
|
'hidden',
|
35 |
85ad3d82
|
Assos Assos
|
'number',
|
36 |
|
|
'textfield',
|
37 |
|
|
),
|
38 |
|
|
'custom_data' => array(
|
39 |
65389548
|
Assos Assos
|
'label' => t('Numeric validation range'),
|
40 |
|
|
'description' => t('Optionally specify the minimum-maximum range to validate the user-entered numeric value against. Usage:') . theme('table', array(
|
41 |
|
|
'header' => array(t('Value'), t('Meaning')),
|
42 |
|
|
'rows' => array(
|
43 |
|
|
array(t('(empty)'), t('No value validation')),
|
44 |
|
|
array('100', t('Greater than or equal to 100')),
|
45 |
|
|
array('|100', t('Less than or equal to 100 (including negative numbers)')),
|
46 |
|
|
array('0|100', t('Greater than or equal to 0 & less than or equal to 100')),
|
47 |
|
|
array('10|100', t('Greater than or equal to 10 & less than or equal to 100')),
|
48 |
|
|
array('-100|-10', t('Greater than or equal to -100 & less than or equal to -10')),
|
49 |
|
|
),
|
50 |
|
|
)),
|
51 |
|
|
'validate_regex' => '/^((-?[\d.]+)?\|)?(-?[\d.]+)$/',
|
52 |
85ad3d82
|
Assos Assos
|
'required' => FALSE,
|
53 |
|
|
),
|
54 |
|
|
'description' => t('Verifies that user-entered values are numeric, with the option to specify min and / or max values.'),
|
55 |
|
|
),
|
56 |
|
|
'min_length' => array(
|
57 |
|
|
'name' => t('Minimum length'),
|
58 |
|
|
'component_types' => array(
|
59 |
|
|
'email',
|
60 |
|
|
'hidden',
|
61 |
5c451ca3
|
Assos Assos
|
'number',
|
62 |
|
|
'textarea',
|
63 |
|
|
'textfield',
|
64 |
85ad3d82
|
Assos Assos
|
),
|
65 |
|
|
'custom_data' => array(
|
66 |
|
|
'label' => t('Minimum number of characters'),
|
67 |
|
|
'description' => t('Specify the minimum number of characters that have to be entered to pass validation.'),
|
68 |
65389548
|
Assos Assos
|
'validate_regex' => '/^\d+$/',
|
69 |
85ad3d82
|
Assos Assos
|
),
|
70 |
a2baadd1
|
Assos Assos
|
'description' => t('Verifies that a user-entered value contains at least the specified number of characters.'),
|
71 |
85ad3d82
|
Assos Assos
|
),
|
72 |
|
|
'max_length' => array(
|
73 |
|
|
'name' => t('Maximum length'),
|
74 |
|
|
'component_types' => array(
|
75 |
|
|
'email',
|
76 |
|
|
'hidden',
|
77 |
5c451ca3
|
Assos Assos
|
'number',
|
78 |
|
|
'textarea',
|
79 |
|
|
'textfield',
|
80 |
85ad3d82
|
Assos Assos
|
),
|
81 |
|
|
'custom_data' => array(
|
82 |
|
|
'label' => t('Maximum number of characters'),
|
83 |
|
|
'description' => t('Specify the maximum number of characters that can be entered to pass validation.'),
|
84 |
65389548
|
Assos Assos
|
'validate_regex' => '/^\d+$/',
|
85 |
85ad3d82
|
Assos Assos
|
),
|
86 |
a2baadd1
|
Assos Assos
|
'description' => t('Verifies that a user-entered value contains at most the specified number of characters.'),
|
87 |
85ad3d82
|
Assos Assos
|
),
|
88 |
|
|
'min_words' => array(
|
89 |
|
|
'name' => t('Minimum number of words'),
|
90 |
|
|
'component_types' => array(
|
91 |
|
|
'hidden',
|
92 |
|
|
'html_textarea',
|
93 |
5c451ca3
|
Assos Assos
|
'textarea',
|
94 |
|
|
'textfield',
|
95 |
85ad3d82
|
Assos Assos
|
),
|
96 |
|
|
'custom_data' => array(
|
97 |
|
|
'label' => t('Minimum number of words'),
|
98 |
9df8b457
|
Assos Assos
|
'description' => t('Specify the minimum number of words that have to be entered to pass validation. Words are defined as strings of letters separated by spaces.'),
|
99 |
65389548
|
Assos Assos
|
'validate_regex' => '/^\d+$/',
|
100 |
85ad3d82
|
Assos Assos
|
),
|
101 |
|
|
'description' => t('Verifies that a user-entered value contains at least the specified number of words.'),
|
102 |
|
|
),
|
103 |
|
|
'max_words' => array(
|
104 |
|
|
'name' => t('Maximum number of words'),
|
105 |
|
|
'component_types' => array(
|
106 |
|
|
'hidden',
|
107 |
|
|
'html_textarea',
|
108 |
5c451ca3
|
Assos Assos
|
'textarea',
|
109 |
|
|
'textfield',
|
110 |
85ad3d82
|
Assos Assos
|
),
|
111 |
|
|
'custom_data' => array(
|
112 |
|
|
'label' => t('Maximum number of words'),
|
113 |
9df8b457
|
Assos Assos
|
'description' => t('Specify the maximum number of words that have to be entered to pass validation. Words are defined as strings of letters separated by spaces.'),
|
114 |
65389548
|
Assos Assos
|
'validate_regex' => '/^\d+$/',
|
115 |
85ad3d82
|
Assos Assos
|
),
|
116 |
|
|
'description' => t('Verifies that a user-entered value contains at most the specified number of words.'),
|
117 |
|
|
),
|
118 |
bb746689
|
Assos Assos
|
// Only available in Webform 4; removed below if not.
|
119 |
5c451ca3
|
Assos Assos
|
'sum' => array(
|
120 |
|
|
'name' => t('Adds up to'),
|
121 |
|
|
'component_types' => array(
|
122 |
|
|
'number',
|
123 |
|
|
),
|
124 |
|
|
'custom_data' => array(
|
125 |
|
|
'label' => t('Number the fields add up to'),
|
126 |
81b16cc2
|
Assos Assos
|
'description' => t('Specify the number and the type of comparison. For example:') . theme('item_list', array(
|
127 |
|
|
'items' => array(
|
128 |
|
|
t('Enter "=3" if the components must add up to exactly 3.'),
|
129 |
|
|
t('Enter ">10" if the components must add up to greater than 10.'),
|
130 |
|
|
t('Enter ">=10" if the components must add up to greater than or equal to 10.'),
|
131 |
|
|
t('Enter "<20" if the components must add up to less than 20.'),
|
132 |
|
|
t('Enter "<=20" if the components must add up to less than or equal to 20.'),
|
133 |
|
|
),
|
134 |
|
|
)),
|
135 |
65389548
|
Assos Assos
|
'validate_regex' => '/^(=|>|>=|<|<=)(-?[\d.]+)$/',
|
136 |
5c451ca3
|
Assos Assos
|
),
|
137 |
|
|
'description' => t('Require the values of the selected fields to add up to exactly, greater than or equal to, or less than or equal to a specified number.'),
|
138 |
|
|
),
|
139 |
85ad3d82
|
Assos Assos
|
'equal' => array(
|
140 |
|
|
'name' => t('Equal values'),
|
141 |
|
|
'component_types' => array(
|
142 |
5c451ca3
|
Assos Assos
|
'date',
|
143 |
85ad3d82
|
Assos Assos
|
'email',
|
144 |
|
|
'hidden',
|
145 |
5c451ca3
|
Assos Assos
|
'number',
|
146 |
|
|
'select',
|
147 |
|
|
'textarea',
|
148 |
|
|
'textfield',
|
149 |
|
|
'time',
|
150 |
9df8b457
|
Assos Assos
|
'boolean',
|
151 |
85ad3d82
|
Assos Assos
|
),
|
152 |
|
|
'min_components' => 2,
|
153 |
5c451ca3
|
Assos Assos
|
'description' => t('Verifies that all specified components contain equal values. If all components are of type email, they will get case-insensitive comparison.'),
|
154 |
85ad3d82
|
Assos Assos
|
),
|
155 |
|
|
'comparison' => array(
|
156 |
|
|
'name' => t('Compare two values'),
|
157 |
|
|
'component_types' => array(
|
158 |
|
|
'date',
|
159 |
|
|
'email',
|
160 |
|
|
'hidden',
|
161 |
|
|
'number',
|
162 |
|
|
'select',
|
163 |
5c451ca3
|
Assos Assos
|
'textarea',
|
164 |
|
|
'textfield',
|
165 |
85ad3d82
|
Assos Assos
|
'time',
|
166 |
|
|
),
|
167 |
|
|
'custom_error' => TRUE,
|
168 |
|
|
'custom_data' => array(
|
169 |
|
|
'label' => t('Comparison operator'),
|
170 |
5c451ca3
|
Assos Assos
|
'description' => t('Specify the comparison operator you want to use. Must be one of: >, >=, <, <=. The validator will compare the first component with the second using this operator. If the components are of type email, they will get case-insensitive comparison.'),
|
171 |
65389548
|
Assos Assos
|
'validate_regex' => '/^(>|>=|<|<=)$/',
|
172 |
85ad3d82
|
Assos Assos
|
),
|
173 |
|
|
'min_components' => 2,
|
174 |
|
|
'max_components' => 2,
|
175 |
e4c061ad
|
Assos Assos
|
'description' => t('Compare two values for greater than (>), less than (<), greater than or equal to (>=), or less than or equal to (<=).'),
|
176 |
85ad3d82
|
Assos Assos
|
),
|
177 |
|
|
'unique' => array(
|
178 |
|
|
'name' => t('Unique values'),
|
179 |
|
|
'component_types' => array(
|
180 |
5c451ca3
|
Assos Assos
|
'date',
|
181 |
85ad3d82
|
Assos Assos
|
'email',
|
182 |
|
|
'hidden',
|
183 |
5c451ca3
|
Assos Assos
|
'number',
|
184 |
|
|
'select',
|
185 |
|
|
'textarea',
|
186 |
|
|
'textfield',
|
187 |
|
|
'time',
|
188 |
9df8b457
|
Assos Assos
|
'boolean',
|
189 |
85ad3d82
|
Assos Assos
|
),
|
190 |
|
|
'min_components' => 2,
|
191 |
5c451ca3
|
Assos Assos
|
'description' => t('Verifies that none of the specified components contain the same value as another selected component in this submission. (To check that values are unique between submissions, use the unique validation option on the "Edit component" page for that component.) If all components are of type email, they will get case-insensitive comparison.'),
|
192 |
85ad3d82
|
Assos Assos
|
),
|
193 |
|
|
'specific_value' => array(
|
194 |
|
|
'name' => t('Specific value(s)'),
|
195 |
|
|
'negatable' => TRUE,
|
196 |
|
|
'component_types' => array(
|
197 |
5c451ca3
|
Assos Assos
|
'email',
|
198 |
|
|
'hidden',
|
199 |
85ad3d82
|
Assos Assos
|
'number',
|
200 |
|
|
'select',
|
201 |
|
|
'textarea',
|
202 |
5c451ca3
|
Assos Assos
|
'textfield',
|
203 |
9df8b457
|
Assos Assos
|
'boolean',
|
204 |
85ad3d82
|
Assos Assos
|
),
|
205 |
|
|
'custom_error' => TRUE,
|
206 |
|
|
'custom_data' => array(
|
207 |
|
|
'label' => t('(Key) value'),
|
208 |
|
|
'description' => t('Specify the specific value(s) you want the component to contain. Separate multiple options by a comma. For components that have keys, use the key value instead.'),
|
209 |
|
|
),
|
210 |
|
|
'description' => t('Verifies that the value of the specified component is from a list of allowed values.'),
|
211 |
|
|
),
|
212 |
|
|
'default_value' => array(
|
213 |
|
|
'name' => t('Default value'),
|
214 |
|
|
'negatable' => TRUE,
|
215 |
|
|
'component_types' => array(
|
216 |
|
|
'email',
|
217 |
|
|
'hidden',
|
218 |
5c451ca3
|
Assos Assos
|
'number',
|
219 |
|
|
'select',
|
220 |
|
|
'textarea',
|
221 |
|
|
'textfield',
|
222 |
9df8b457
|
Assos Assos
|
'boolean',
|
223 |
85ad3d82
|
Assos Assos
|
),
|
224 |
|
|
'custom_error' => TRUE,
|
225 |
|
|
'description' => t('Verifies that the user-entered value is the default value for that component. Negate if you want not the default value.'),
|
226 |
|
|
),
|
227 |
a2baadd1
|
Assos Assos
|
'someofseveral' => array(
|
228 |
5c451ca3
|
Assos Assos
|
'name' => t('Some of several'),
|
229 |
85ad3d82
|
Assos Assos
|
'component_types' => array(
|
230 |
5c451ca3
|
Assos Assos
|
'date',
|
231 |
85ad3d82
|
Assos Assos
|
'email',
|
232 |
5c451ca3
|
Assos Assos
|
'file',
|
233 |
|
|
'number',
|
234 |
85ad3d82
|
Assos Assos
|
'select',
|
235 |
5c451ca3
|
Assos Assos
|
'textarea',
|
236 |
|
|
'textfield',
|
237 |
9df8b457
|
Assos Assos
|
'time',
|
238 |
|
|
'boolean',
|
239 |
85ad3d82
|
Assos Assos
|
),
|
240 |
a2baadd1
|
Assos Assos
|
'custom_data' => array(
|
241 |
5c451ca3
|
Assos Assos
|
'label' => t('Number to be completed'),
|
242 |
81b16cc2
|
Assos Assos
|
'description' => t('Specify the number that must be completed and the type of comparison. For example:') . theme('item_list', array(
|
243 |
|
|
'items' => array(
|
244 |
|
|
t('Enter ">=1" if the user must complete <b>at least</b> 1 of the selected components.'),
|
245 |
|
|
t('Enter "=3" if the user must complete <b>exactly</b> 3 of the selected components.'),
|
246 |
|
|
t('Enter "<=2" if the user must complete <b>at most</b> 2 of the selected components.'),
|
247 |
|
|
),
|
248 |
|
|
)),
|
249 |
65389548
|
Assos Assos
|
'validate_regex' => '/^[><]?=\d+$/',
|
250 |
85ad3d82
|
Assos Assos
|
),
|
251 |
|
|
'min_components' => 2,
|
252 |
5c451ca3
|
Assos Assos
|
'description' => t('Requires the user to complete some number of components out of a group of components. For example, complete at least 2 out of 3, complete at most 4 out of 6, or complete exactly 3 our of 4.'),
|
253 |
85ad3d82
|
Assos Assos
|
),
|
254 |
|
|
'select_min' => array(
|
255 |
|
|
'name' => t('Minimum number of selections required'),
|
256 |
|
|
'component_types' => array(
|
257 |
|
|
'select',
|
258 |
|
|
),
|
259 |
|
|
'custom_data' => array(
|
260 |
|
|
'label' => t('Minimum number of selections'),
|
261 |
|
|
'description' => t('Specify the minimum number of options a user should select.'),
|
262 |
65389548
|
Assos Assos
|
'validate_regex' => '/^\d+$/',
|
263 |
85ad3d82
|
Assos Assos
|
),
|
264 |
|
|
'description' => t('Forces the user to select at least a defined number of options from the specified webform components.'),
|
265 |
|
|
),
|
266 |
|
|
'select_max' => array(
|
267 |
|
|
'name' => t('Maximum number of selections allowed'),
|
268 |
|
|
'component_types' => array(
|
269 |
|
|
'select',
|
270 |
|
|
),
|
271 |
|
|
'custom_data' => array(
|
272 |
|
|
'label' => t('Maximum number of selections'),
|
273 |
|
|
'description' => t('Specify the maximum number of options a user can select.'),
|
274 |
65389548
|
Assos Assos
|
'validate_regex' => '/^\d+$/',
|
275 |
85ad3d82
|
Assos Assos
|
),
|
276 |
|
|
'description' => t('Forces the user to select at most a defined number of options from the specified webform components.'),
|
277 |
|
|
),
|
278 |
|
|
'select_exact' => array(
|
279 |
|
|
'name' => t('Exact number of selections required'),
|
280 |
|
|
'negatable' => TRUE,
|
281 |
|
|
'component_types' => array(
|
282 |
|
|
'select',
|
283 |
|
|
),
|
284 |
|
|
'custom_data' => array(
|
285 |
|
|
'label' => t('Number of selections'),
|
286 |
|
|
'description' => t('Specify how many options a user can select.'),
|
287 |
65389548
|
Assos Assos
|
'validate_regex' => '/^\d+$/',
|
288 |
85ad3d82
|
Assos Assos
|
),
|
289 |
|
|
'description' => t('Forces the user to select exactly the defined number of options from the specified webform components.'),
|
290 |
|
|
),
|
291 |
|
|
'plain_text' => array(
|
292 |
|
|
'name' => t('Plain text (disallow tags)'),
|
293 |
|
|
'negatable' => TRUE,
|
294 |
|
|
'component_types' => array(
|
295 |
|
|
'email',
|
296 |
|
|
'hidden',
|
297 |
5c451ca3
|
Assos Assos
|
'textarea',
|
298 |
|
|
'textfield',
|
299 |
85ad3d82
|
Assos Assos
|
),
|
300 |
81b16cc2
|
Assos Assos
|
'description' => t("Verifies that user-entered data doesn't contain HTML tags."),
|
301 |
85ad3d82
|
Assos Assos
|
),
|
302 |
|
|
'starts_with' => array(
|
303 |
|
|
'name' => t('Starts with'),
|
304 |
|
|
'negatable' => TRUE,
|
305 |
|
|
'component_types' => array(
|
306 |
|
|
'email',
|
307 |
|
|
'hidden',
|
308 |
5c451ca3
|
Assos Assos
|
'number',
|
309 |
|
|
'textarea',
|
310 |
|
|
'textfield',
|
311 |
85ad3d82
|
Assos Assos
|
),
|
312 |
|
|
'custom_data' => array(
|
313 |
|
|
'label' => t('Starts with'),
|
314 |
|
|
'description' => t('Enter the text that this field must start with.'),
|
315 |
|
|
),
|
316 |
|
|
'description' => t('Verifies that user-entered data starts with a given string.'),
|
317 |
|
|
),
|
318 |
|
|
'ends_with' => array(
|
319 |
|
|
'name' => t('Ends with'),
|
320 |
|
|
'negatable' => TRUE,
|
321 |
|
|
'component_types' => array(
|
322 |
|
|
'email',
|
323 |
|
|
'hidden',
|
324 |
5c451ca3
|
Assos Assos
|
'number',
|
325 |
|
|
'textarea',
|
326 |
|
|
'textfield',
|
327 |
85ad3d82
|
Assos Assos
|
),
|
328 |
|
|
'custom_data' => array(
|
329 |
|
|
'label' => t('Ends with'),
|
330 |
|
|
'description' => t('Enter the text that this field must end with.'),
|
331 |
|
|
),
|
332 |
|
|
'description' => t('Verifies that user-entered data ends with a given string.'),
|
333 |
|
|
),
|
334 |
|
|
'pattern' => array(
|
335 |
5c451ca3
|
Assos Assos
|
'name' => t('Pattern'),
|
336 |
85ad3d82
|
Assos Assos
|
'component_types' => array(
|
337 |
|
|
'hidden',
|
338 |
5c451ca3
|
Assos Assos
|
'textarea',
|
339 |
|
|
'textfield',
|
340 |
85ad3d82
|
Assos Assos
|
),
|
341 |
|
|
'custom_error' => TRUE,
|
342 |
|
|
'custom_data' => array(
|
343 |
|
|
'label' => t('Pattern'),
|
344 |
81b16cc2
|
Assos Assos
|
'description' => t('Specify a pattern where:') . theme('item_list', array('items' => array(t('@ = any letter A-Z'), t('# = any numeral 0-9'), t('| = separates two or more acceptable patterns'), t('Any other character must appear in its exact position')))) . t('Examples') . theme('item_list', array('items' => array(t('North American phone number: (###) ###-####'), t('D-2500 series model numbers: D-25##'), t('UK Postal Code: @# #@@|@## #@@|@@# #@@|@@## #@@|@#@ #@@|@@#@ #@@|GIR0AA')))),
|
345 |
85ad3d82
|
Assos Assos
|
),
|
346 |
|
|
'description' => t('Verifies that a user-entered value follows to a specified pattern.'),
|
347 |
|
|
),
|
348 |
|
|
'regex' => array(
|
349 |
|
|
'name' => t('Regular expression, case-sensitive'),
|
350 |
|
|
'negatable' => TRUE,
|
351 |
|
|
'component_types' => array(
|
352 |
|
|
'email',
|
353 |
|
|
'hidden',
|
354 |
5c451ca3
|
Assos Assos
|
'number',
|
355 |
|
|
'textarea',
|
356 |
|
|
'textfield',
|
357 |
85ad3d82
|
Assos Assos
|
),
|
358 |
|
|
'custom_error' => TRUE,
|
359 |
|
|
'custom_data' => array(
|
360 |
4f315dab
|
Assos Assos
|
'label' => t('Regex code (case-sensitive)'),
|
361 |
|
|
'description' => t('Specify regex code to validate the user input against. Do not include delimiters such as /.'),
|
362 |
85ad3d82
|
Assos Assos
|
),
|
363 |
4f315dab
|
Assos Assos
|
'description' => t('Validates user-entered text against a case-sensitive regular expression.'),
|
364 |
85ad3d82
|
Assos Assos
|
),
|
365 |
|
|
'regexi' => array(
|
366 |
|
|
'name' => t('Regular expression, case-insensitive'),
|
367 |
|
|
'negatable' => TRUE,
|
368 |
|
|
'component_types' => array(
|
369 |
|
|
'email',
|
370 |
|
|
'hidden',
|
371 |
5c451ca3
|
Assos Assos
|
'number',
|
372 |
|
|
'textarea',
|
373 |
|
|
'textfield',
|
374 |
85ad3d82
|
Assos Assos
|
),
|
375 |
|
|
'custom_error' => TRUE,
|
376 |
|
|
'custom_data' => array(
|
377 |
4f315dab
|
Assos Assos
|
'label' => t('Regex code (case-insensitive)'),
|
378 |
|
|
'description' => t('Specify regex code to validate the user input against. Do not include delimiters such as /.'),
|
379 |
85ad3d82
|
Assos Assos
|
),
|
380 |
4f315dab
|
Assos Assos
|
'description' => t('Validates user-entered text against a case-insensitive regular expression.'),
|
381 |
85ad3d82
|
Assos Assos
|
),
|
382 |
|
|
'must_be_empty' => array(
|
383 |
|
|
'name' => t('Must be empty'),
|
384 |
|
|
'component_types' => array(
|
385 |
5c451ca3
|
Assos Assos
|
'hidden',
|
386 |
85ad3d82
|
Assos Assos
|
'number',
|
387 |
5c451ca3
|
Assos Assos
|
'textarea',
|
388 |
85ad3d82
|
Assos Assos
|
'textfield',
|
389 |
|
|
),
|
390 |
|
|
'description' => t('Verifies that a specified textfield remains empty. Recommended use case: used as an anti-spam measure by hiding the element with CSS.'),
|
391 |
|
|
),
|
392 |
|
|
'blacklist' => array(
|
393 |
|
|
'name' => t('Words blacklist'),
|
394 |
|
|
'negatable' => TRUE,
|
395 |
|
|
'component_types' => array(
|
396 |
|
|
'email',
|
397 |
|
|
'hidden',
|
398 |
5c451ca3
|
Assos Assos
|
'textarea',
|
399 |
|
|
'textfield',
|
400 |
85ad3d82
|
Assos Assos
|
),
|
401 |
|
|
'custom_error' => TRUE,
|
402 |
|
|
'custom_data' => array(
|
403 |
|
|
'label' => t('Blacklisted words'),
|
404 |
|
|
'description' => t('Specify illegal words, seperated by commas.'),
|
405 |
|
|
),
|
406 |
81b16cc2
|
Assos Assos
|
'description' => t("Validates that user-entered data doesn't contain any of the specified illegal words."),
|
407 |
85ad3d82
|
Assos Assos
|
),
|
408 |
9df8b457
|
Assos Assos
|
'username' => array(
|
409 |
85ad3d82
|
Assos Assos
|
'name' => t('Must match a username'),
|
410 |
|
|
'negatable' => TRUE,
|
411 |
|
|
'component_types' => array(
|
412 |
|
|
'hidden',
|
413 |
5c451ca3
|
Assos Assos
|
'textfield',
|
414 |
85ad3d82
|
Assos Assos
|
),
|
415 |
|
|
'description' => t('Validates that user-entered data matches a username.'),
|
416 |
|
|
),
|
417 |
|
|
'valid_url' => array(
|
418 |
5c451ca3
|
Assos Assos
|
'name' => t('Valid URL'),
|
419 |
85ad3d82
|
Assos Assos
|
'negatable' => TRUE,
|
420 |
|
|
'component_types' => array(
|
421 |
|
|
'hidden',
|
422 |
5c451ca3
|
Assos Assos
|
'textfield',
|
423 |
85ad3d82
|
Assos Assos
|
),
|
424 |
|
|
'description' => t('Validates that the user-entered data is a valid URL.'),
|
425 |
|
|
),
|
426 |
|
|
);
|
427 |
|
|
|
428 |
bb746689
|
Assos Assos
|
// Only available in Webform 4.
|
429 |
|
|
module_load_include('inc', 'webform', 'components/number');
|
430 |
|
|
if (!function_exists('webform_compare_floats')) {
|
431 |
|
|
unset($validators['sum']);
|
432 |
|
|
}
|
433 |
|
|
|
434 |
85ad3d82
|
Assos Assos
|
if (module_exists('email_verify')) {
|
435 |
|
|
$validators['email_verify'] = array(
|
436 |
5c451ca3
|
Assos Assos
|
'name' => t('Email Verify'),
|
437 |
85ad3d82
|
Assos Assos
|
'component_types' => array(
|
438 |
|
|
'email',
|
439 |
|
|
),
|
440 |
|
|
'description' => t('Verifies that an email address actually exists using the <a href="https://drupal.org/project/email_verify">Email Verification module</a>.'),
|
441 |
|
|
);
|
442 |
|
|
}
|
443 |
|
|
|
444 |
|
|
return $validators;
|
445 |
|
|
}
|
446 |
|
|
|
447 |
|
|
/**
|
448 |
|
|
* Implements hook_webform_validation_validate().
|
449 |
|
|
*/
|
450 |
|
|
function webform_validation_webform_validation_validate($validator_name, $items, $components, $rule) {
|
451 |
5c451ca3
|
Assos Assos
|
if (!$items) {
|
452 |
|
|
return NULL;
|
453 |
|
|
}
|
454 |
|
|
|
455 |
65389548
|
Assos Assos
|
// Allow translation for all components item names if available.
|
456 |
|
|
if (module_exists('webform_localization')) {
|
457 |
|
|
foreach ($components as &$component) {
|
458 |
|
|
$dummy_element = array(
|
459 |
|
|
'#title' => '',
|
460 |
|
|
);
|
461 |
|
|
_webform_localization_translate_component($dummy_element, $component);
|
462 |
|
|
if (isset($dummy_element['#title']) && (string) $dummy_element['#title']) {
|
463 |
|
|
$component['name'] = $dummy_element['#title'];
|
464 |
|
|
}
|
465 |
|
|
}
|
466 |
|
|
}
|
467 |
|
|
|
468 |
5c451ca3
|
Assos Assos
|
// For certain validators, if all components to be compared are email
|
469 |
|
|
// components, make the values lower-case to avoid case-sensitive comparison.
|
470 |
|
|
if (in_array($validator_name, array('equal', 'comparison', 'unique'))) {
|
471 |
|
|
$all_email = TRUE;
|
472 |
|
|
foreach ($rule['components'] as $component) {
|
473 |
|
|
if ($component['type'] !== 'email') {
|
474 |
|
|
$all_email = FALSE;
|
475 |
|
|
break;
|
476 |
a2baadd1
|
Assos Assos
|
}
|
477 |
|
|
}
|
478 |
5c451ca3
|
Assos Assos
|
if ($all_email) {
|
479 |
|
|
$items = array_map('strtolower', $items);
|
480 |
|
|
}
|
481 |
|
|
}
|
482 |
a2baadd1
|
Assos Assos
|
|
483 |
76bdcd04
|
Assos Assos
|
// Some components, such as multiple select, send their values as arrays,
|
484 |
|
|
// others don't. Convert all to arrays and write the rules to handle them that
|
485 |
|
|
// way. Remove empty values.
|
486 |
5c451ca3
|
Assos Assos
|
foreach ($items as $key => $val) {
|
487 |
|
|
$new_values = array();
|
488 |
|
|
foreach ((array) $val as $val_key => $val_val) {
|
489 |
|
|
if ((string) $val_val !== '') {
|
490 |
|
|
$new_values[$val_key] = $val_val;
|
491 |
|
|
}
|
492 |
|
|
}
|
493 |
|
|
$items[$key] = $new_values;
|
494 |
|
|
}
|
495 |
e4c061ad
|
Assos Assos
|
// Ensure later calls to key() get the first item.
|
496 |
|
|
reset($items);
|
497 |
85ad3d82
|
Assos Assos
|
|
498 |
5c451ca3
|
Assos Assos
|
$errors = array();
|
499 |
|
|
switch ($validator_name) {
|
500 |
|
|
case 'numeric':
|
501 |
|
|
$num_range = _webform_numeric_check_data($rule['data']);
|
502 |
|
|
foreach ($items as $key => $val) {
|
503 |
|
|
foreach ($val as $subval) {
|
504 |
81b16cc2
|
Assos Assos
|
// First check if the value is numeric.
|
505 |
5c451ca3
|
Assos Assos
|
if (is_numeric($subval)) {
|
506 |
|
|
$subval = (float) $subval;
|
507 |
|
|
}
|
508 |
|
|
else {
|
509 |
|
|
$errors[$key] = t('%item is not numeric.', array('%item' => $components[$key]['name']));
|
510 |
|
|
continue;
|
511 |
|
|
}
|
512 |
|
|
|
513 |
76bdcd04
|
Assos Assos
|
// Now validate the entered numeric value against the validator range
|
514 |
|
|
// settings, if appropriate.
|
515 |
81b16cc2
|
Assos Assos
|
// a. validate min & max.
|
516 |
5c451ca3
|
Assos Assos
|
if (isset($num_range['min']) && isset($num_range['max'])) {
|
517 |
81b16cc2
|
Assos Assos
|
// Validate the min - max range.
|
518 |
5c451ca3
|
Assos Assos
|
if ($subval < $num_range['min'] || $subval > $num_range['max']) {
|
519 |
81b16cc2
|
Assos Assos
|
$errors[$key] = t('%item is not within the allowed range %range.', array('%item' => $components[$key]['name'], '%range' => str_replace('|', ' - ', $rule['data'])));
|
520 |
85ad3d82
|
Assos Assos
|
}
|
521 |
5c451ca3
|
Assos Assos
|
}
|
522 |
|
|
else {
|
523 |
81b16cc2
|
Assos Assos
|
// b. validate min.
|
524 |
5c451ca3
|
Assos Assos
|
if (isset($num_range['min'])) {
|
525 |
|
|
if ($subval < $num_range['min']) {
|
526 |
|
|
$errors[$key] = t('%item should be greater than or equal to %val.', array('%item' => $components[$key]['name'], '%val' => $num_range['min']));
|
527 |
85ad3d82
|
Assos Assos
|
}
|
528 |
5c451ca3
|
Assos Assos
|
}
|
529 |
81b16cc2
|
Assos Assos
|
// c. validate max.
|
530 |
5c451ca3
|
Assos Assos
|
if (isset($num_range['max'])) {
|
531 |
|
|
if ($subval > $num_range['max']) {
|
532 |
|
|
$errors[$key] = t('%item should be less than or equal to %val.', array('%item' => $components[$key]['name'], '%val' => $num_range['max']));
|
533 |
85ad3d82
|
Assos Assos
|
}
|
534 |
|
|
}
|
535 |
|
|
}
|
536 |
|
|
}
|
537 |
5c451ca3
|
Assos Assos
|
}
|
538 |
|
|
return $errors;
|
539 |
81b16cc2
|
Assos Assos
|
|
540 |
5c451ca3
|
Assos Assos
|
case 'min_length':
|
541 |
|
|
$min_length = $rule['data'];
|
542 |
|
|
foreach ($items as $key => $val) {
|
543 |
|
|
foreach ($val as $subval) {
|
544 |
|
|
if (drupal_strlen($subval) < $min_length) {
|
545 |
|
|
$errors[$key] = t('%item should be at least %num characters long.', array('%item' => $components[$key]['name'], '%num' => $min_length));
|
546 |
85ad3d82
|
Assos Assos
|
}
|
547 |
|
|
}
|
548 |
5c451ca3
|
Assos Assos
|
}
|
549 |
|
|
return $errors;
|
550 |
81b16cc2
|
Assos Assos
|
|
551 |
5c451ca3
|
Assos Assos
|
case 'max_length':
|
552 |
|
|
$max_length = $rule['data'];
|
553 |
|
|
foreach ($items as $key => $val) {
|
554 |
|
|
foreach ($val as $subval) {
|
555 |
|
|
if (drupal_strlen($subval) > $max_length) {
|
556 |
|
|
$errors[$key] = t('%item should be at most %num characters long.', array('%item' => $components[$key]['name'], '%num' => $max_length));
|
557 |
85ad3d82
|
Assos Assos
|
}
|
558 |
|
|
}
|
559 |
5c451ca3
|
Assos Assos
|
}
|
560 |
|
|
return $errors;
|
561 |
81b16cc2
|
Assos Assos
|
|
562 |
5c451ca3
|
Assos Assos
|
case 'min_words':
|
563 |
|
|
$min_words = $rule['data'];
|
564 |
|
|
foreach ($items as $key => $val) {
|
565 |
|
|
foreach ($val as $subval) {
|
566 |
|
|
if (_webform_validation_count_words($subval) < $min_words) {
|
567 |
|
|
$error = format_plural($min_words, '%item should be at least 1 word long.', '%item should be at least @count words long.', array('%item' => $components[$key]['name']));
|
568 |
|
|
$errors[$key] = $error;
|
569 |
85ad3d82
|
Assos Assos
|
}
|
570 |
|
|
}
|
571 |
5c451ca3
|
Assos Assos
|
}
|
572 |
|
|
return $errors;
|
573 |
81b16cc2
|
Assos Assos
|
|
574 |
5c451ca3
|
Assos Assos
|
case 'max_words':
|
575 |
|
|
$max_words = $rule['data'];
|
576 |
|
|
foreach ($items as $key => $val) {
|
577 |
|
|
foreach ($val as $subval) {
|
578 |
|
|
if (_webform_validation_count_words($subval) > $max_words) {
|
579 |
|
|
$error = format_plural($max_words, '%item should be at most 1 word long.', '%item should be at most @count words long.', array('%item' => $components[$key]['name']));
|
580 |
|
|
$errors[$key] = $error;
|
581 |
85ad3d82
|
Assos Assos
|
}
|
582 |
|
|
}
|
583 |
5c451ca3
|
Assos Assos
|
}
|
584 |
|
|
return $errors;
|
585 |
81b16cc2
|
Assos Assos
|
|
586 |
5c451ca3
|
Assos Assos
|
case 'sum':
|
587 |
|
|
// Get the numbers to sum.
|
588 |
|
|
$sum = array();
|
589 |
|
|
foreach ($items as $item) {
|
590 |
|
|
if (isset($item[0])) {
|
591 |
|
|
$sum[] = $item[0];
|
592 |
|
|
}
|
593 |
|
|
}
|
594 |
|
|
// If none of the components are completed, don't run this validator.
|
595 |
|
|
if (!count($sum)) {
|
596 |
|
|
return array();
|
597 |
|
|
}
|
598 |
|
|
$sum = array_sum($sum);
|
599 |
|
|
|
600 |
|
|
// Number being compared with.
|
601 |
|
|
$compare_number = (float) preg_replace('/^[^0-9]+/', '', $rule['data']);
|
602 |
|
|
|
603 |
|
|
// Parse the comparision operator and do comparison.
|
604 |
bb746689
|
Assos Assos
|
module_load_include('inc', 'webform', 'components/number');
|
605 |
5c451ca3
|
Assos Assos
|
$error = FALSE;
|
606 |
|
|
if (substr($rule['data'], 0, 2) === '<=') {
|
607 |
bb746689
|
Assos Assos
|
if (!(webform_compare_floats($sum, $compare_number) <= 0)) {
|
608 |
5c451ca3
|
Assos Assos
|
$error = t('less than or equal to');
|
609 |
|
|
}
|
610 |
|
|
}
|
611 |
|
|
elseif (substr($rule['data'], 0, 1) === '<') {
|
612 |
bb746689
|
Assos Assos
|
if (!(webform_compare_floats($sum, $compare_number) < 0)) {
|
613 |
5c451ca3
|
Assos Assos
|
$error = t('less than');
|
614 |
|
|
}
|
615 |
|
|
}
|
616 |
|
|
elseif (substr($rule['data'], 0, 2) === '>=') {
|
617 |
bb746689
|
Assos Assos
|
if (!(webform_compare_floats($sum, $compare_number) >= 0)) {
|
618 |
5c451ca3
|
Assos Assos
|
$error = t('greater than or equal to');
|
619 |
|
|
}
|
620 |
|
|
}
|
621 |
|
|
elseif (substr($rule['data'], 0, 1) === '>') {
|
622 |
bb746689
|
Assos Assos
|
if (!(webform_compare_floats($sum, $compare_number) > 0)) {
|
623 |
5c451ca3
|
Assos Assos
|
$error = t('greater than');
|
624 |
|
|
}
|
625 |
|
|
}
|
626 |
|
|
else {
|
627 |
bb746689
|
Assos Assos
|
if (!(webform_compare_floats($sum, $compare_number) === 0)) {
|
628 |
5c451ca3
|
Assos Assos
|
$error = t('exactly');
|
629 |
|
|
}
|
630 |
|
|
}
|
631 |
|
|
// Set error if needed.
|
632 |
|
|
if ($error) {
|
633 |
|
|
$keys = array_keys($items);
|
634 |
|
|
$errors[$keys[0]] = t('These items must add up to %verb %compare_number:', array('%verb' => $error, '%compare_number' => $compare_number)) . theme('item_list', array('items' => _webform_validation_get_names_of_rule_components($rule)));
|
635 |
|
|
}
|
636 |
|
|
return $errors;
|
637 |
81b16cc2
|
Assos Assos
|
|
638 |
5c451ca3
|
Assos Assos
|
case 'equal':
|
639 |
|
|
$first_entry_key = key($items);
|
640 |
|
|
$first_entry = array_shift($items);
|
641 |
|
|
foreach ($items as $key => $val) {
|
642 |
|
|
if ($val !== $first_entry) {
|
643 |
|
|
$errors[$key] = t('%item_checked does not match %item_first.', array('%item_checked' => $components[$key]['name'], '%item_first' => $components[$first_entry_key]['name']));
|
644 |
|
|
}
|
645 |
|
|
}
|
646 |
|
|
return $errors;
|
647 |
81b16cc2
|
Assos Assos
|
|
648 |
5c451ca3
|
Assos Assos
|
case 'comparison':
|
649 |
|
|
foreach (array(1, 2) as $count) {
|
650 |
|
|
$entry[$count]['key'] = key($items);
|
651 |
|
|
$value = array_shift($items);
|
652 |
|
|
if ($components[$entry[$count]['key']]['type'] === 'date') {
|
653 |
1f623f01
|
Assos Assos
|
if (!empty($value) && checkdate((int) $value['month'], (int) $value['day'], (int) $value['year'])) {
|
654 |
5c451ca3
|
Assos Assos
|
$entry[$count]['value'] = date('Y-m-d', mktime(0, 0, 0, (int) $value['month'], (int) $value['day'], (int) $value['year']));
|
655 |
|
|
}
|
656 |
|
|
else {
|
657 |
|
|
$entry[$count]['value'] = NULL;
|
658 |
85ad3d82
|
Assos Assos
|
}
|
659 |
|
|
}
|
660 |
5c451ca3
|
Assos Assos
|
elseif ($components[$entry[$count]['key']]['type'] === 'time') {
|
661 |
65389548
|
Assos Assos
|
if (isset($value['hour']) && isset($value['minute'])) {
|
662 |
|
|
$time = $value['hour'] . ':' . str_pad($value['minute'], 2, '0', STR_PAD_LEFT);
|
663 |
|
|
if (!empty($value['ampm'])) {
|
664 |
|
|
$time .= ' ' . $value['ampm'];
|
665 |
|
|
}
|
666 |
|
|
$time = strtotime($time);
|
667 |
|
|
}
|
668 |
|
|
else {
|
669 |
|
|
$time = NULL;
|
670 |
85ad3d82
|
Assos Assos
|
}
|
671 |
5c451ca3
|
Assos Assos
|
if ($time) {
|
672 |
|
|
$entry[$count]['value'] = date('H:i', $time);
|
673 |
85ad3d82
|
Assos Assos
|
}
|
674 |
|
|
else {
|
675 |
5c451ca3
|
Assos Assos
|
$entry[$count]['value'] = NULL;
|
676 |
85ad3d82
|
Assos Assos
|
}
|
677 |
|
|
}
|
678 |
5c451ca3
|
Assos Assos
|
else {
|
679 |
|
|
$entry[$count]['value'] = _webform_validation_flatten_array($value);
|
680 |
85ad3d82
|
Assos Assos
|
}
|
681 |
5c451ca3
|
Assos Assos
|
}
|
682 |
85ad3d82
|
Assos Assos
|
|
683 |
5c451ca3
|
Assos Assos
|
// Don't validate if either are empty.
|
684 |
|
|
if ((string) $entry[1]['value'] === '' || (string) $entry[2]['value'] === '') {
|
685 |
|
|
return array();
|
686 |
|
|
}
|
687 |
85ad3d82
|
Assos Assos
|
|
688 |
5c451ca3
|
Assos Assos
|
$error = FALSE;
|
689 |
|
|
switch ($rule['data']) {
|
690 |
|
|
case '>':
|
691 |
|
|
if (!($entry[1]['value'] > $entry[2]['value'])) {
|
692 |
|
|
$error = TRUE;
|
693 |
85ad3d82
|
Assos Assos
|
}
|
694 |
5c451ca3
|
Assos Assos
|
break;
|
695 |
81b16cc2
|
Assos Assos
|
|
696 |
5c451ca3
|
Assos Assos
|
case '>=':
|
697 |
|
|
if (!($entry[1]['value'] >= $entry[2]['value'])) {
|
698 |
|
|
$error = TRUE;
|
699 |
|
|
}
|
700 |
|
|
break;
|
701 |
81b16cc2
|
Assos Assos
|
|
702 |
5c451ca3
|
Assos Assos
|
case '<':
|
703 |
|
|
if (!($entry[1]['value'] < $entry[2]['value'])) {
|
704 |
|
|
$error = TRUE;
|
705 |
|
|
}
|
706 |
|
|
break;
|
707 |
81b16cc2
|
Assos Assos
|
|
708 |
5c451ca3
|
Assos Assos
|
case '<=':
|
709 |
|
|
if (!($entry[1]['value'] <= $entry[2]['value'])) {
|
710 |
|
|
$error = TRUE;
|
711 |
|
|
}
|
712 |
|
|
break;
|
713 |
|
|
}
|
714 |
|
|
|
715 |
|
|
if ($error) {
|
716 |
|
|
$errors[$entry[2]['key']] = _webform_validation_i18n_error_message($rule);
|
717 |
|
|
}
|
718 |
|
|
return $errors;
|
719 |
81b16cc2
|
Assos Assos
|
|
720 |
5c451ca3
|
Assos Assos
|
case 'unique':
|
721 |
|
|
foreach ($items as $key => $val) {
|
722 |
|
|
$items[$key] = _webform_validation_flatten_array($val);
|
723 |
|
|
}
|
724 |
76bdcd04
|
Assos Assos
|
// Now we count how many times each value appears, and find out which
|
725 |
|
|
// values appear more than once.
|
726 |
5c451ca3
|
Assos Assos
|
$items_count = array_count_values(array_map('drupal_strtolower', array_map('trim', $items)));
|
727 |
76bdcd04
|
Assos Assos
|
$doubles = array_filter($items_count, function ($x) {
|
728 |
|
|
return $x > 1;
|
729 |
|
|
});
|
730 |
5c451ca3
|
Assos Assos
|
foreach ($items as $key => $val) {
|
731 |
|
|
if (in_array(drupal_strtolower($val), array_keys($doubles))) {
|
732 |
|
|
$errors[$key] = t('The value of %item is not unique.', array('%item' => $components[$key]['name']));
|
733 |
85ad3d82
|
Assos Assos
|
}
|
734 |
5c451ca3
|
Assos Assos
|
}
|
735 |
|
|
return $errors;
|
736 |
81b16cc2
|
Assos Assos
|
|
737 |
5c451ca3
|
Assos Assos
|
case 'specific_value':
|
738 |
|
|
$specific_values = explode(',', $rule['data']);
|
739 |
|
|
$specific_values = array_map('trim', $specific_values);
|
740 |
|
|
foreach ($items as $key => $val) {
|
741 |
76bdcd04
|
Assos Assos
|
// Selects: Fail if at least one checked and at least one not in the
|
742 |
|
|
// allowed values.
|
743 |
5c451ca3
|
Assos Assos
|
$val = array_filter($val);
|
744 |
|
|
$test = count($val) && count(array_diff($val, $specific_values));
|
745 |
|
|
_webform_validation_test($errors, $key, $rule, $test);
|
746 |
|
|
}
|
747 |
|
|
return $errors;
|
748 |
81b16cc2
|
Assos Assos
|
|
749 |
5c451ca3
|
Assos Assos
|
case 'default_value':
|
750 |
|
|
foreach ($items as $key => $val) {
|
751 |
|
|
$val = _webform_validation_flatten_array($val);
|
752 |
|
|
$test = $val != $components[$key]['value'];
|
753 |
|
|
_webform_validation_test($errors, $key, $rule, $test);
|
754 |
|
|
}
|
755 |
|
|
return $errors;
|
756 |
81b16cc2
|
Assos Assos
|
|
757 |
5c451ca3
|
Assos Assos
|
case 'someofseveral':
|
758 |
|
|
// Determine the number of components completed.
|
759 |
|
|
foreach ($items as $key => $val) {
|
760 |
|
|
$items[$key] = _webform_validation_flatten_array($val);
|
761 |
|
|
$items[$key] = (bool) strlen($items[$key]);
|
762 |
|
|
}
|
763 |
|
|
$number_completed = count(array_filter($items));
|
764 |
|
|
|
765 |
|
|
// Number being compared with.
|
766 |
|
|
$compare_number = (int) preg_replace('/[^0-9]+/', '', $rule['data']);
|
767 |
|
|
if ($compare_number < 1) {
|
768 |
|
|
$compare_number = 1;
|
769 |
|
|
}
|
770 |
|
|
elseif ($compare_number > count($rule['components'])) {
|
771 |
|
|
$compare_number = count($rule['components']);
|
772 |
|
|
}
|
773 |
|
|
|
774 |
|
|
// Parse the comparision operator and do comparison.
|
775 |
|
|
$error = FALSE;
|
776 |
|
|
if (substr($rule['data'], 0, 1) === '=') {
|
777 |
|
|
if (!($number_completed === $compare_number)) {
|
778 |
|
|
$error = t('exactly');
|
779 |
85ad3d82
|
Assos Assos
|
}
|
780 |
5c451ca3
|
Assos Assos
|
}
|
781 |
|
|
elseif (substr($rule['data'], 0, 2) === '<=') {
|
782 |
|
|
if (!($number_completed <= $compare_number)) {
|
783 |
|
|
$error = t('at most');
|
784 |
85ad3d82
|
Assos Assos
|
}
|
785 |
5c451ca3
|
Assos Assos
|
}
|
786 |
|
|
else {
|
787 |
|
|
if (!($number_completed >= $compare_number)) {
|
788 |
|
|
$error = t('at least');
|
789 |
85ad3d82
|
Assos Assos
|
}
|
790 |
5c451ca3
|
Assos Assos
|
}
|
791 |
|
|
|
792 |
|
|
// Set error if needed.
|
793 |
|
|
if ($error) {
|
794 |
|
|
$keys = array_keys($items);
|
795 |
|
|
$errors[$keys[0]] = t('You must complete %verb %compare_number of these items:', array('%verb' => $error, '%compare_number' => $compare_number)) . theme('item_list', array('items' => _webform_validation_get_names_of_rule_components($rule)));
|
796 |
|
|
}
|
797 |
|
|
return $errors;
|
798 |
81b16cc2
|
Assos Assos
|
|
799 |
5c451ca3
|
Assos Assos
|
case 'select_min':
|
800 |
|
|
$min_selections = $rule['data'];
|
801 |
|
|
foreach ($items as $key => $val) {
|
802 |
|
|
if (count(array_filter($val, '_webform_validation_check_false')) < $min_selections) {
|
803 |
|
|
$errors[$key] = t('Please select at least %num options for %item.', array('%num' => $min_selections, '%item' => $components[$key]['name']));
|
804 |
85ad3d82
|
Assos Assos
|
}
|
805 |
5c451ca3
|
Assos Assos
|
}
|
806 |
|
|
return $errors;
|
807 |
81b16cc2
|
Assos Assos
|
|
808 |
5c451ca3
|
Assos Assos
|
case 'select_max':
|
809 |
|
|
$max_selections = $rule['data'];
|
810 |
|
|
foreach ($items as $key => $val) {
|
811 |
|
|
if (count(array_filter($val, '_webform_validation_check_false')) > $max_selections) {
|
812 |
|
|
$errors[$key] = t('Please select maximum %num options for %item.', array('%num' => $max_selections, '%item' => $components[$key]['name']));
|
813 |
85ad3d82
|
Assos Assos
|
}
|
814 |
5c451ca3
|
Assos Assos
|
}
|
815 |
|
|
return $errors;
|
816 |
81b16cc2
|
Assos Assos
|
|
817 |
5c451ca3
|
Assos Assos
|
case 'select_exact':
|
818 |
|
|
$allowed_selections = $rule['data'];
|
819 |
|
|
foreach ($items as $key => $val) {
|
820 |
|
|
$error_strings = array(
|
821 |
|
|
'regular' => 'Please select %num options for %item.',
|
822 |
|
|
'negated' => 'Please do not select %num options for %item.',
|
823 |
|
|
);
|
824 |
|
|
$error_vars = array('%num' => $allowed_selections, '%item' => $components[$key]['name']);
|
825 |
|
|
$test = count(array_filter($val, '_webform_validation_check_false')) != $allowed_selections;
|
826 |
|
|
_webform_validation_test($errors, $key, $rule, $test, $error_strings, $error_vars);
|
827 |
|
|
}
|
828 |
|
|
return $errors;
|
829 |
81b16cc2
|
Assos Assos
|
|
830 |
5c451ca3
|
Assos Assos
|
case 'plain_text':
|
831 |
|
|
foreach ($items as $key => $val) {
|
832 |
|
|
$error_strings = array(
|
833 |
|
|
'regular' => '%item only allows the use of plain text.',
|
834 |
|
|
'negated' => '%item must contain HTML tags.',
|
835 |
|
|
);
|
836 |
|
|
$error_vars = array('%item' => $components[$key]['name']);
|
837 |
|
|
foreach ($val as $subval) {
|
838 |
|
|
$test = strcmp($subval, strip_tags($subval));
|
839 |
85ad3d82
|
Assos Assos
|
_webform_validation_test($errors, $key, $rule, $test, $error_strings, $error_vars);
|
840 |
|
|
}
|
841 |
5c451ca3
|
Assos Assos
|
}
|
842 |
|
|
return $errors;
|
843 |
81b16cc2
|
Assos Assos
|
|
844 |
5c451ca3
|
Assos Assos
|
case 'starts_with':
|
845 |
|
|
case 'ends_with':
|
846 |
|
|
$pattern = preg_quote($rule['data'], '/');
|
847 |
|
|
if ($validator_name === 'starts_with') {
|
848 |
|
|
$pattern = '^' . $pattern;
|
849 |
|
|
$verb = t('start');
|
850 |
|
|
}
|
851 |
|
|
else {
|
852 |
|
|
$pattern .= '$';
|
853 |
|
|
$verb = t('end');
|
854 |
|
|
}
|
855 |
|
|
$pattern = '/' . $pattern . '/';
|
856 |
|
|
|
857 |
|
|
foreach ($items as $key => $val) {
|
858 |
|
|
$error_strings = array(
|
859 |
|
|
'regular' => '%item must %verb with "%string".',
|
860 |
|
|
'negated' => '%item must not %verb with "%string".',
|
861 |
|
|
);
|
862 |
|
|
$error_vars = array('%item' => $components[$key]['name'], '%verb' => $verb, '%string' => $rule['data']);
|
863 |
|
|
foreach ($val as $subval) {
|
864 |
|
|
$test = !preg_match($pattern, $subval);
|
865 |
|
|
_webform_validation_test($errors, $key, $rule, $test, $error_strings, $error_vars);
|
866 |
85ad3d82
|
Assos Assos
|
}
|
867 |
5c451ca3
|
Assos Assos
|
}
|
868 |
|
|
return $errors;
|
869 |
81b16cc2
|
Assos Assos
|
|
870 |
5c451ca3
|
Assos Assos
|
case 'pattern':
|
871 |
|
|
$pattern = preg_quote($rule['data'], '/');
|
872 |
|
|
$pattern = str_replace('@', '[a-zA-Z]', $pattern);
|
873 |
|
|
$pattern = str_replace('#', '[0-9]', $pattern);
|
874 |
|
|
$pattern = '(' . $pattern . ')';
|
875 |
|
|
// Un-escape "|" operator.
|
876 |
|
|
$pattern = preg_replace('/(\\s*)(\\\\)(\\|)(\\s*)/', ')|(', $pattern);
|
877 |
|
|
foreach ($items as $key => $val) {
|
878 |
|
|
foreach ($val as $subval) {
|
879 |
|
|
$test = !preg_match('/^(' . $pattern . ')$/', $subval);
|
880 |
|
|
_webform_validation_test($errors, $key, $rule, $test);
|
881 |
85ad3d82
|
Assos Assos
|
}
|
882 |
5c451ca3
|
Assos Assos
|
}
|
883 |
|
|
return $errors;
|
884 |
81b16cc2
|
Assos Assos
|
|
885 |
5c451ca3
|
Assos Assos
|
case 'regex':
|
886 |
|
|
case 'regexi':
|
887 |
|
|
mb_regex_encoding('UTF-8');
|
888 |
|
|
$regex = $rule['data'];
|
889 |
|
|
foreach ($items as $key => $val) {
|
890 |
|
|
foreach ($val as $subval) {
|
891 |
|
|
if ($validator_name === 'regexi') {
|
892 |
|
|
$match = (bool) mb_eregi($regex, $subval);
|
893 |
a2baadd1
|
Assos Assos
|
}
|
894 |
5c451ca3
|
Assos Assos
|
else {
|
895 |
|
|
$match = (bool) mb_ereg($regex, $subval);
|
896 |
a2baadd1
|
Assos Assos
|
}
|
897 |
5c451ca3
|
Assos Assos
|
$test = !$match;
|
898 |
|
|
_webform_validation_test($errors, $key, $rule, $test);
|
899 |
85ad3d82
|
Assos Assos
|
}
|
900 |
5c451ca3
|
Assos Assos
|
}
|
901 |
|
|
return $errors;
|
902 |
81b16cc2
|
Assos Assos
|
|
903 |
5c451ca3
|
Assos Assos
|
case 'must_be_empty':
|
904 |
|
|
foreach ($items as $key => $val) {
|
905 |
|
|
if (count($val) !== 0) {
|
906 |
|
|
$errors[$key] = t('%item does not contain the correct data.', array('%item' => $components[$key]['name']));
|
907 |
85ad3d82
|
Assos Assos
|
}
|
908 |
5c451ca3
|
Assos Assos
|
}
|
909 |
|
|
return $errors;
|
910 |
81b16cc2
|
Assos Assos
|
|
911 |
5c451ca3
|
Assos Assos
|
case 'blacklist':
|
912 |
|
|
$blacklist = preg_quote($rule['data'], '/');
|
913 |
|
|
$blacklist = explode(',', $blacklist);
|
914 |
|
|
$blacklist = array_map('trim', $blacklist);
|
915 |
|
|
$blacklist = '/\b(' . implode('|', $blacklist) . ')\b/i';
|
916 |
|
|
foreach ($items as $key => $val) {
|
917 |
|
|
foreach ($val as $subval) {
|
918 |
|
|
$test = preg_match($blacklist, $subval);
|
919 |
|
|
_webform_validation_test($errors, $key, $rule, $test);
|
920 |
85ad3d82
|
Assos Assos
|
}
|
921 |
5c451ca3
|
Assos Assos
|
}
|
922 |
|
|
return $errors;
|
923 |
81b16cc2
|
Assos Assos
|
|
924 |
5c451ca3
|
Assos Assos
|
case 'username':
|
925 |
|
|
foreach ($items as $key => $val) {
|
926 |
|
|
$error_strings = array(
|
927 |
|
|
'regular' => 'The %item field does not match an active username.',
|
928 |
|
|
'negated' => 'The %item field matches an active username.',
|
929 |
|
|
);
|
930 |
|
|
$error_vars = array('%item' => $components[$key]['name']);
|
931 |
|
|
foreach ($val as $subval) {
|
932 |
|
|
$test = !db_query_range('SELECT 1 FROM {users} WHERE name = :username AND status = 1', 0, 1, array(':username' => $subval))->fetchField();
|
933 |
|
|
_webform_validation_test($errors, $key, $rule, $test, $error_strings, $error_vars);
|
934 |
85ad3d82
|
Assos Assos
|
}
|
935 |
5c451ca3
|
Assos Assos
|
}
|
936 |
|
|
return $errors;
|
937 |
81b16cc2
|
Assos Assos
|
|
938 |
5c451ca3
|
Assos Assos
|
case 'valid_url':
|
939 |
|
|
foreach ($items as $key => $val) {
|
940 |
|
|
$error_strings = array(
|
941 |
|
|
'regular' => '%item does not appear to be a valid URL.',
|
942 |
|
|
'negated' => '%item must not be a valid URL.',
|
943 |
|
|
);
|
944 |
|
|
$error_vars = array('%item' => $components[$key]['name']);
|
945 |
|
|
foreach ($val as $subval) {
|
946 |
|
|
$test = !valid_url($subval, TRUE);
|
947 |
|
|
_webform_validation_test($errors, $key, $rule, $test, $error_strings, $error_vars);
|
948 |
85ad3d82
|
Assos Assos
|
}
|
949 |
5c451ca3
|
Assos Assos
|
}
|
950 |
|
|
return $errors;
|
951 |
81b16cc2
|
Assos Assos
|
|
952 |
5c451ca3
|
Assos Assos
|
case 'email_verify':
|
953 |
|
|
if (module_exists('email_verify')) {
|
954 |
85ad3d82
|
Assos Assos
|
foreach ($items as $key => $val) {
|
955 |
a2baadd1
|
Assos Assos
|
foreach ($val as $subval) {
|
956 |
5c451ca3
|
Assos Assos
|
$error = email_verify_check($subval);
|
957 |
|
|
if ($error) {
|
958 |
|
|
$errors[$key] = $error;
|
959 |
85ad3d82
|
Assos Assos
|
}
|
960 |
|
|
}
|
961 |
|
|
}
|
962 |
5c451ca3
|
Assos Assos
|
}
|
963 |
|
|
return $errors;
|
964 |
85ad3d82
|
Assos Assos
|
}
|
965 |
|
|
}
|
966 |
|
|
|
967 |
5c451ca3
|
Assos Assos
|
/**
|
968 |
|
|
* Return an array of the names of the components in a validation rule.
|
969 |
|
|
*
|
970 |
81b16cc2
|
Assos Assos
|
* @param array $rule
|
971 |
5c451ca3
|
Assos Assos
|
* Array of information about a validation rule.
|
972 |
|
|
*
|
973 |
|
|
* @return array
|
974 |
|
|
* Array of the filtered names of the components in $rule.
|
975 |
|
|
*/
|
976 |
|
|
function _webform_validation_get_names_of_rule_components(array $rule) {
|
977 |
|
|
$names = array();
|
978 |
|
|
foreach ($rule['components'] as $component) {
|
979 |
|
|
$names[] = _webform_filter_xss($component['name']);
|
980 |
|
|
}
|
981 |
|
|
return $names;
|
982 |
|
|
}
|
983 |
|
|
|
984 |
85ad3d82
|
Assos Assos
|
/**
|
985 |
76bdcd04
|
Assos Assos
|
* Helper function to negate validation rules as needed.
|
986 |
|
|
*
|
987 |
|
|
* Creates the correct error message.
|
988 |
85ad3d82
|
Assos Assos
|
*/
|
989 |
|
|
function _webform_validation_test(&$errors, $key, $rule, $test, array $error_strings = NULL, array $error_vars = NULL) {
|
990 |
|
|
$rule['negate'] = !empty($rule['negate']);
|
991 |
|
|
if ($rule['negate']) {
|
992 |
|
|
$test = !$test;
|
993 |
|
|
}
|
994 |
|
|
if ($test) {
|
995 |
|
|
if ($error_strings) {
|
996 |
|
|
$error = t($error_strings[$rule['negate'] ? 'negated' : 'regular'], $error_vars);
|
997 |
|
|
}
|
998 |
|
|
else {
|
999 |
|
|
$error = _webform_validation_i18n_error_message($rule);
|
1000 |
|
|
}
|
1001 |
|
|
$errors[$key] = $error;
|
1002 |
|
|
}
|
1003 |
|
|
}
|
1004 |
|
|
|
1005 |
|
|
/**
|
1006 |
|
|
* Count the number of words in a value.
|
1007 |
a2baadd1
|
Assos Assos
|
*
|
1008 |
|
|
* Strip HTML first.
|
1009 |
1f623f01
|
Assos Assos
|
*
|
1010 |
|
|
* @param string|array $val
|
1011 |
|
|
* A string or array of strings in which to count words.
|
1012 |
|
|
*
|
1013 |
|
|
* @return int
|
1014 |
|
|
* The number of words in the input.
|
1015 |
85ad3d82
|
Assos Assos
|
*/
|
1016 |
|
|
function _webform_validation_count_words($val) {
|
1017 |
a2baadd1
|
Assos Assos
|
$val = _webform_validation_flatten_array($val);
|
1018 |
|
|
|
1019 |
1f623f01
|
Assos Assos
|
// Strip any HTML tags so they're not counted in the word count.
|
1020 |
a2baadd1
|
Assos Assos
|
$val = strip_tags($val);
|
1021 |
1f623f01
|
Assos Assos
|
// Convert character entities back to characters. Without this, entities for
|
1022 |
|
|
// whitespace characters would not be counted as word boundaries.
|
1023 |
|
|
$val = html_entity_decode($val);
|
1024 |
a2baadd1
|
Assos Assos
|
|
1025 |
1f623f01
|
Assos Assos
|
return count(preg_split('/[[:space:]\xC2\xA0]+/', $val));
|
1026 |
85ad3d82
|
Assos Assos
|
}
|
1027 |
|
|
|
1028 |
|
|
/**
|
1029 |
81b16cc2
|
Assos Assos
|
* Helper function to deal with submitted values that are arrays.
|
1030 |
|
|
*
|
1031 |
|
|
* For example, multiple select component. We flatten the array as a
|
1032 |
|
|
* comma-separated list to do the comparison.
|
1033 |
85ad3d82
|
Assos Assos
|
*/
|
1034 |
|
|
function _webform_validation_flatten_array($val) {
|
1035 |
|
|
if (is_array($val)) {
|
1036 |
|
|
$arr = array_filter($val, '_webform_validation_check_false');
|
1037 |
|
|
return implode(',', $arr);
|
1038 |
|
|
}
|
1039 |
|
|
return $val;
|
1040 |
|
|
}
|
1041 |
|
|
|
1042 |
|
|
/**
|
1043 |
81b16cc2
|
Assos Assos
|
* Get a array of validator definitions.
|
1044 |
5c451ca3
|
Assos Assos
|
*
|
1045 |
81b16cc2
|
Assos Assos
|
* @return array
|
1046 |
|
|
* Information about validators.
|
1047 |
85ad3d82
|
Assos Assos
|
*/
|
1048 |
|
|
function webform_validation_get_validators() {
|
1049 |
81b16cc2
|
Assos Assos
|
static $validators;
|
1050 |
|
|
if ($validators) {
|
1051 |
|
|
return $validators;
|
1052 |
|
|
}
|
1053 |
|
|
|
1054 |
85ad3d82
|
Assos Assos
|
$validators = module_invoke_all('webform_validation_validators');
|
1055 |
76bdcd04
|
Assos Assos
|
// Let modules use hook_webform_validator_alter($validators) to change
|
1056 |
|
|
// validator settings.
|
1057 |
85ad3d82
|
Assos Assos
|
drupal_alter('webform_validator', $validators);
|
1058 |
5c451ca3
|
Assos Assos
|
|
1059 |
|
|
// Remove entries for which only partial information exists.
|
1060 |
|
|
foreach ($validators as $validator_key => $validator_info) {
|
1061 |
|
|
if (!isset($validator_info['name']) || !isset($validator_info['component_types'])) {
|
1062 |
|
|
unset($validators[$validator_key]);
|
1063 |
|
|
}
|
1064 |
|
|
}
|
1065 |
|
|
|
1066 |
85ad3d82
|
Assos Assos
|
return $validators;
|
1067 |
|
|
}
|
1068 |
|
|
|
1069 |
|
|
/**
|
1070 |
5c451ca3
|
Assos Assos
|
* Return an array of the names of the validators.
|
1071 |
|
|
*
|
1072 |
|
|
* @return array
|
1073 |
|
|
* Array of with keys being validator IDs and values validator names.
|
1074 |
85ad3d82
|
Assos Assos
|
*/
|
1075 |
|
|
function webform_validation_get_validators_selection() {
|
1076 |
|
|
$selection = array();
|
1077 |
|
|
$validators = webform_validation_get_validators();
|
1078 |
|
|
if ($validators) {
|
1079 |
|
|
foreach ($validators as $validator_key => $validator_info) {
|
1080 |
|
|
$selection[$validator_key] = $validator_info['name'];
|
1081 |
|
|
}
|
1082 |
|
|
}
|
1083 |
|
|
return $selection;
|
1084 |
|
|
}
|
1085 |
|
|
|
1086 |
|
|
/**
|
1087 |
81b16cc2
|
Assos Assos
|
* Get a list of valid component types per validator.
|
1088 |
|
|
*
|
1089 |
|
|
* These are defined via hook_webform_validation_validators(). If "all" is
|
1090 |
|
|
* specified, all available component types will be returned.
|
1091 |
85ad3d82
|
Assos Assos
|
*/
|
1092 |
|
|
function webform_validation_valid_component_types($validator) {
|
1093 |
|
|
$validators = webform_validation_get_validators();
|
1094 |
|
|
if ($info = $validators[$validator]) {
|
1095 |
|
|
$allowed_types = $info['component_types'];
|
1096 |
5c451ca3
|
Assos Assos
|
if (in_array('all', $allowed_types, TRUE)) {
|
1097 |
85ad3d82
|
Assos Assos
|
return array_keys(webform_components());
|
1098 |
|
|
}
|
1099 |
|
|
return $info['component_types'];
|
1100 |
|
|
}
|
1101 |
|
|
}
|
1102 |
|
|
|
1103 |
|
|
/**
|
1104 |
5c451ca3
|
Assos Assos
|
* Return information about a specified validator.
|
1105 |
|
|
*
|
1106 |
81b16cc2
|
Assos Assos
|
* @param string $validator_key
|
1107 |
5c451ca3
|
Assos Assos
|
* The key of the validator to return information about.
|
1108 |
|
|
*
|
1109 |
|
|
* @return array
|
1110 |
|
|
* Array of information about the validator.
|
1111 |
85ad3d82
|
Assos Assos
|
*/
|
1112 |
|
|
function webform_validation_get_validator_info($validator_key) {
|
1113 |
|
|
$validators = webform_validation_get_validators();
|
1114 |
|
|
return $validators[$validator_key];
|
1115 |
|
|
}
|
1116 |
|
|
|
1117 |
|
|
/**
|
1118 |
81b16cc2
|
Assos Assos
|
* Handle translatable error messages, if available.
|
1119 |
85ad3d82
|
Assos Assos
|
*/
|
1120 |
|
|
function _webform_validation_i18n_error_message($rule) {
|
1121 |
|
|
$rule['error_message'] = filter_xss($rule['error_message']);
|
1122 |
a2baadd1
|
Assos Assos
|
if (module_exists('i18n')) {
|
1123 |
|
|
return i18n_string('webform_validation:error_message:' . $rule['ruleid'] . ':message', $rule['error_message']);
|
1124 |
85ad3d82
|
Assos Assos
|
}
|
1125 |
|
|
return $rule['error_message'];
|
1126 |
|
|
}
|
1127 |
|
|
|
1128 |
|
|
/**
|
1129 |
4f315dab
|
Assos Assos
|
* Helper function used by array_filter() to determine if a value is empty.
|
1130 |
|
|
*
|
1131 |
|
|
* This is used in place of empty() because string '0' needs to be considered
|
1132 |
|
|
* not empty and return FALSE.
|
1133 |
|
|
*
|
1134 |
|
|
* @param mixed $var
|
1135 |
|
|
* The value to check.
|
1136 |
|
|
*
|
1137 |
|
|
* @return bool
|
1138 |
|
|
* TRUE if $var is not one of FALSE, int 0, or empty string; FALSE otherwise.
|
1139 |
|
|
*
|
1140 |
|
|
* @see https://www.drupal.org/node/886458
|
1141 |
|
|
* @see https://www.drupal.org/node/2638172
|
1142 |
85ad3d82
|
Assos Assos
|
*/
|
1143 |
|
|
function _webform_validation_check_false($var) {
|
1144 |
4f315dab
|
Assos Assos
|
return $var !== FALSE && $var !== 0 && $var !== '';
|
1145 |
85ad3d82
|
Assos Assos
|
}
|
1146 |
|
|
|
1147 |
|
|
/**
|
1148 |
76bdcd04
|
Assos Assos
|
* Helper function to check numeric data.
|
1149 |
|
|
*
|
1150 |
|
|
* Process the numeric value validation range that was provided in the numeric
|
1151 |
|
|
* validator options.
|
1152 |
85ad3d82
|
Assos Assos
|
*/
|
1153 |
|
|
function _webform_numeric_check_data($data) {
|
1154 |
|
|
$range = array('min' => NULL, 'max' => NULL);
|
1155 |
81b16cc2
|
Assos Assos
|
// If no value was specified, don't validate.
|
1156 |
85ad3d82
|
Assos Assos
|
if ($data == '') {
|
1157 |
|
|
return $range;
|
1158 |
|
|
}
|
1159 |
|
|
|
1160 |
81b16cc2
|
Assos Assos
|
// If only one numeric value was specified, this is the min value.
|
1161 |
85ad3d82
|
Assos Assos
|
if (is_numeric($data)) {
|
1162 |
|
|
$range['min'] = (float) $data;
|
1163 |
|
|
}
|
1164 |
|
|
|
1165 |
|
|
if (strpos($data, '|') !== FALSE) {
|
1166 |
|
|
list($min, $max) = explode('|', $data);
|
1167 |
|
|
if ($min != '' && is_numeric($min)) {
|
1168 |
|
|
$range['min'] = (float) $min;
|
1169 |
|
|
}
|
1170 |
|
|
if ($max != '' && is_numeric($max)) {
|
1171 |
|
|
$range['max'] = (float) $max;
|
1172 |
|
|
}
|
1173 |
|
|
}
|
1174 |
|
|
return $range;
|
1175 |
|
|
} |