PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.5.5
Secure Custom Fields v6.5.5
6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / includes / validation.php
secure-custom-fields / includes Last commit date
Blocks 1 year ago Meta 1 year ago admin 11 months ago ajax 1 year ago api 1 year ago fields 1 year ago forms 1 year ago legacy 1 year ago locations 1 year ago post-types 1 year ago rest-api 11 months ago walkers 1 year ago acf-bidirectional-functions.php 1 year ago acf-field-functions.php 1 year ago acf-field-group-functions.php 1 year ago acf-form-functions.php 1 year ago acf-helper-functions.php 1 year ago acf-hook-functions.php 1 year ago acf-input-functions.php 1 year ago acf-internal-post-type-functions.php 1 year ago acf-meta-functions.php 1 year ago acf-post-functions.php 1 year ago acf-post-type-functions.php 1 year ago acf-taxonomy-functions.php 1 year ago acf-user-functions.php 1 year ago acf-utility-functions.php 1 year ago acf-value-functions.php 1 year ago acf-wp-functions.php 1 year ago assets.php 1 year ago blocks.php 1 year ago class-acf-data.php 1 year ago class-acf-internal-post-type.php 1 year ago class-acf-options-page.php 1 year ago class-acf-site-health.php 1 year ago compatibility.php 1 year ago deprecated.php 1 year ago fields.php 1 year ago index.php 1 year ago l10n.php 1 year ago local-fields.php 1 year ago local-json.php 1 year ago local-meta.php 1 year ago locations.php 1 year ago loop.php 1 year ago media.php 1 year ago rest-api.php 1 year ago revisions.php 1 year ago scf-ui-options-page-functions.php 1 year ago third-party.php 1 year ago upgrades.php 1 year ago validation.php 1 year ago wpml.php 1 year ago
validation.php
402 lines
1 <?php // phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed, PEAR.NamingConventions.ValidClassName
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7 if ( ! class_exists( 'acf_validation' ) ) :
8 #[AllowDynamicProperties]
9 /**
10 * Validation Class
11 */
12 class acf_validation {
13
14 /**
15 * Array of errors.
16 *
17 * @var array $errors
18 */
19 public $errors = array();
20 /**
21 * This function will setup the class functionality
22 *
23 * @type function
24 * @date 5/03/2014
25 * @since ACF 5.0.0
26 *
27 * @return void
28 */
29 public function __construct() {
30
31 // vars
32 $this->errors = array();
33
34 // ajax
35 add_action( 'wp_ajax_acf/validate_save_post', array( $this, 'ajax_validate_save_post' ) );
36 add_action( 'wp_ajax_nopriv_acf/validate_save_post', array( $this, 'ajax_validate_save_post' ) );
37 add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 5 );
38 }
39
40
41 /**
42 * This function will add an error message for a field
43 *
44 * @type function
45 * @date 25/11/2013
46 * @since ACF 5.0.0
47 *
48 * @param string $input name attribute of DOM element.
49 * @param string $message error message.
50 */
51 public function add_error( $input, $message ) {
52
53 // add to array
54 $this->errors[] = array(
55 'input' => $input,
56 'message' => $message,
57 );
58 }
59
60
61 /**
62 * This function will return an error for a given input
63 *
64 * @type function
65 * @date 5/03/2016
66 * @since ACF 5.3.2
67 *
68 * @param string $input name attribute of DOM element.
69 * @return array|bool
70 */
71 public function get_error( $input ) {
72
73 // bail early if no errors
74 if ( empty( $this->errors ) ) {
75 return false;
76 }
77
78 // loop
79 foreach ( $this->errors as $error ) {
80 if ( $error['input'] === $input ) {
81 return $error;
82 }
83 }
84
85 // return
86 return false;
87 }
88
89
90 /**
91 * This function will return validation errors
92 *
93 * @type function
94 * @date 25/11/2013
95 * @since ACF 5.0.0
96 *
97 * @return array|bool
98 */
99 public function get_errors() {
100
101 // bail early if no errors
102 if ( empty( $this->errors ) ) {
103 return false;
104 }
105
106 // return
107 return $this->errors;
108 }
109
110
111 /**
112 * This function will remove all errors
113 *
114 * @type function
115 * @date 4/03/2016
116 * @since ACF 5.3.2
117 *
118 * @return void
119 */
120 public function reset_errors() {
121
122 $this->errors = array();
123 }
124
125 /**
126 * Validates $_POST data via AJAX prior to save.
127 *
128 * @since ACF 5.0.9
129 *
130 * @return void
131 */
132 public function ajax_validate_save_post() {
133 if ( ! acf_verify_ajax() ) {
134 if ( empty( $_REQUEST['nonce'] ) ) {
135 $nonce_error = __( 'SCF was unable to perform validation because no nonce was received by the server.', 'secure-custom-fields' );
136 } else {
137 $nonce_error = __( 'SCF was unable to perform validation because the provided nonce failed verification.', 'secure-custom-fields' );
138 }
139
140 wp_send_json_success(
141 array(
142 'valid' => 0,
143 'errors' => array(
144 array(
145 'input' => false,
146 'message' => __( 'SCF was unable to perform validation due to an invalid security nonce being provided.', 'secure-custom-fields' ),
147 ),
148 ),
149 )
150 );
151 }
152
153 $json = array(
154 'valid' => 1,
155 'errors' => 0,
156 );
157
158 if ( acf_validate_save_post() ) {
159 wp_send_json_success( $json );
160 }
161
162 $json['valid'] = 0;
163 $json['errors'] = acf_get_validation_errors();
164
165 wp_send_json_success( $json );
166 }
167
168 /**
169 * Loops over $_POST data and validates ACF values.
170 *
171 * @since ACF 5.4.0
172 */
173 public function acf_validate_save_post() {
174 // phpcs:disable WordPress.Security.NonceVerification.Missing -- Verified elsewhere.
175 $post_type = acf_request_arg( 'post_type', false );
176 $screen = acf_request_arg( '_acf_screen', false );
177
178 if ( in_array( $screen, array( 'post_type', 'taxonomy', 'ui_options_page' ), true ) && in_array( $post_type, array( 'acf-post-type', 'acf-taxonomy', 'acf-ui-options-page' ), true ) ) {
179 acf_validate_internal_post_type_values( $post_type );
180 } elseif ( acf_request_arg( 'acf_ui_options_page' ) ) {
181 acf_validate_internal_post_type_values( 'acf-ui-options-page' );
182 } else {
183 // Bail early if no matching $_POST.
184 if ( empty( $_POST['acf'] ) ) {
185 return;
186 }
187
188 acf_validate_values( wp_unslash( $_POST['acf'] ), 'acf' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
189 }
190 // phpcs:enable WordPress.Security.NonceVerification.Missing
191 }
192 }
193
194 // initialize
195 acf()->validation = new acf_validation();
196 endif; // class_exists check
197
198
199 /**
200 * Add validation error.
201 *
202 * Alias of acf()->validation->add_error()
203 *
204 * @type function
205 * @date 6/10/13
206 * @since ACF 5.0.0
207 *
208 * @param string $input name attribute of DOM element.
209 * @param string $message error message.
210 * @return void
211 */
212 function acf_add_validation_error( $input, $message = '' ) {
213 acf()->validation->add_error( $input, $message );
214 }
215
216 /**
217 * Retrieve validation errors.
218 *
219 * Alias of acf()->validation->function()
220 *
221 * @type function
222 * @date 6/10/13
223 * @since ACF 5.0.0
224 *
225 * @return array|bool
226 */
227 function acf_get_validation_errors() {
228 return acf()->validation->get_errors();
229 }
230
231 /**
232 * Get the validation error.
233 *
234 * Alias of acf()->validation->get_error()
235 *
236 * @type function
237 * @date 6/10/13
238 * @since ACF 5.0.0
239 * @since SCF 6.4.1 Added the $input parameter, which is required in the get_error method.
240 *
241 * @param string $input name attribute of DOM element.
242 *
243 * @return string|bool
244 */
245 function acf_get_validation_error( $input ) {
246 return acf()->validation->get_error( $input );
247 }
248
249 /**
250 * Reset Validation errors.
251 *
252 * Alias of acf()->validation->reset_errors()
253 *
254 * @type function
255 * @date 6/10/13
256 * @since ACF 5.0.0
257 *
258 * @return void
259 */
260 function acf_reset_validation_errors() {
261 acf()->validation->reset_errors();
262 }
263
264
265 /**
266 * This function will validate $_POST data and add errors
267 *
268 * @type function
269 * @date 25/11/2013
270 * @since ACF 5.0.0
271 *
272 * @param bool $show_errors if true, errors will be shown via a wp_die screen.
273 * @return bool
274 */
275 function acf_validate_save_post( $show_errors = false ) {
276
277 // action
278 do_action( 'acf/validate_save_post' );
279
280 // vars
281 $errors = acf_get_validation_errors();
282
283 // bail early if no errors
284 if ( ! $errors ) {
285 return true;
286 }
287
288 // show errors
289 if ( $show_errors ) {
290 $message = '<h2>' . __( 'Validation failed', 'secure-custom-fields' ) . '</h2>';
291 $message .= '<ul>';
292 foreach ( $errors as $error ) {
293 $message .= '<li>' . $error['message'] . '</li>';
294 }
295 $message .= '</ul>';
296
297 // die
298 wp_die( acf_esc_html( $message ), esc_html__( 'Validation failed', 'secure-custom-fields' ) );
299 }
300
301 // return
302 return false;
303 }
304
305
306 /**
307 * This function will validate an array of field values
308 *
309 * @type function
310 * @date 6/10/13
311 * @since ACF 5.0.0
312 *
313 * @param array $values An array of field values.
314 * @param string $input_prefix The input element's name attribute.
315 *
316 * @return void
317 */
318 function acf_validate_values( $values, $input_prefix = '' ) {
319
320 // bail early if empty
321 if ( empty( $values ) ) {
322 return;
323 }
324
325 // loop
326 foreach ( $values as $key => $value ) {
327
328 // vars
329 $field = acf_get_field( $key );
330 $input = $input_prefix . '[' . $key . ']';
331
332 // bail early if not found
333 if ( ! $field ) {
334 continue;
335 }
336
337 // validate
338 acf_validate_value( $value, $field, $input );
339 }
340 }
341
342
343 /**
344 * This function will validate a field's value
345 *
346 * @type function
347 * @date 6/10/13
348 * @since ACF 5.0.0
349 *
350 * @param mixed $value The field value to validate.
351 * @param array $field The field array.
352 * @param string $input The input element's name attribute.
353 *
354 * @return boolean
355 */
356 function acf_validate_value( $value, $field, $input ) {
357
358 // vars
359 $valid = true;
360 /* translators: %s: field label */
361 $message = sprintf( __( '%s value is required', 'secure-custom-fields' ), $field['label'] );
362
363 // valid
364 if ( $field['required'] ) {
365
366 // valid is set to false if the value is empty, but allow 0 as a valid value
367 if ( empty( $value ) && ! is_numeric( $value ) ) {
368 $valid = false;
369 }
370 }
371
372 /**
373 * Filters whether the value is valid.
374 *
375 * @date 28/09/13
376 * @since ACF 5.0.0
377 *
378 * @param bool $valid The valid status. Return a string to display a custom error message.
379 * @param mixed $value The value.
380 * @param array $field The field array.
381 * @param string $input The input element's name attribute.
382 */
383 $valid = apply_filters( "acf/validate_value/type={$field['type']}", $valid, $value, $field, $input );
384 $valid = apply_filters( "acf/validate_value/name={$field['_name']}", $valid, $value, $field, $input );
385 $valid = apply_filters( "acf/validate_value/key={$field['key']}", $valid, $value, $field, $input );
386 $valid = apply_filters( 'acf/validate_value', $valid, $value, $field, $input );
387
388 // allow $valid to be a custom error message
389 if ( ! empty( $valid ) && is_string( $valid ) ) {
390 $message = $valid;
391 $valid = false;
392 }
393
394 if ( ! $valid ) {
395 acf_add_validation_error( $input, $message );
396 return false;
397 }
398
399 // return
400 return true;
401 }
402