PluginProbe
Advanced Custom Fields (ACF®) / 6.5.1
Advanced Custom Fields (ACF®) v6.5.1
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / includes / validation.php

validation.php in Advanced Custom Fields (ACF®) 6.5.1, at includes/validation.php

365 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7 if ( ! class_exists( 'acf_validation' ) ) :
8 class acf_validation {
9
10 /**
11 * An array of validation errors.
12 * @var array
13 */
14 public $errors = array();
15
16 /**
17 * This function will setup the class functionality
18 *
19 * @type function
20 * @date 5/03/2014
21 * @since 5.0.0
22 *
23 * @param n/a
24 * @return n/a
25 */
26 function __construct() {
27
28 // ajax
29 add_action( 'wp_ajax_acf/validate_save_post', array( $this, 'ajax_validate_save_post' ) );
30 add_action( 'wp_ajax_nopriv_acf/validate_save_post', array( $this, 'ajax_validate_save_post' ) );
31 add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 5 );
32 }
33
34
35 /**
36 * This function will add an error message for a field
37 *
38 * @type function
39 * @date 25/11/2013
40 * @since 5.0.0
41 *
42 * @param $input (string) name attribute of DOM elmenet
43 * @param $message (string) error message
44 * @return $post_id (int)
45 */
46 function add_error( $input, $message ) {
47
48 // add to array
49 $this->errors[] = array(
50 'input' => $input,
51 'message' => $message,
52 );
53 }
54
55
56 /**
57 * This function will return an error for a given input
58 *
59 * @type function
60 * @date 5/03/2016
61 * @since 5.3.2
62 *
63 * @param $input (string) name attribute of DOM elmenet
64 * @return (mixed)
65 */
66 function get_error( $input ) {
67
68 // bail early if no errors
69 if ( empty( $this->errors ) ) {
70 return false;
71 }
72
73 // loop
74 foreach ( $this->errors as $error ) {
75 if ( $error['input'] === $input ) {
76 return $error;
77 }
78 }
79
80 // return
81 return false;
82 }
83
84
85 /**
86 * This function will return validation errors
87 *
88 * @type function
89 * @date 25/11/2013
90 * @since 5.0.0
91 *
92 * @param n/a
93 * @return (array|boolean)
94 */
95 function get_errors() {
96
97 // bail early if no errors
98 if ( empty( $this->errors ) ) {
99 return false;
100 }
101
102 // return
103 return $this->errors;
104 }
105
106
107 /**
108 * This function will remove all errors
109 *
110 * @type function
111 * @date 4/03/2016
112 * @since 5.3.2
113 *
114 * @param n/a
115 * @return n/a
116 */
117 function reset_errors() {
118
119 $this->errors = array();
120 }
121
122 /**
123 * Validates $_POST data via AJAX prior to save.
124 *
125 * @since 5.0.9
126 *
127 * @return void
128 */
129 public function ajax_validate_save_post() {
130 if ( ! acf_verify_ajax() ) {
131 if ( empty( $_REQUEST['nonce'] ) ) {
132 $nonce_error = __( 'ACF was unable to perform validation because no nonce was received by the server.', 'acf' );
133 } else {
134 $nonce_error = __( 'ACF was unable to perform validation because the provided nonce failed verification.', 'acf' );
135 }
136
137 wp_send_json_success(
138 array(
139 'valid' => 0,
140 'errors' => array(
141 array(
142 'input' => false,
143 'message' => $nonce_error,
144 'action' => array(
145 'label' => __( 'Learn more', 'acf' ),
146 'url' => acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/validation-nonce-errors/', 'docs', 'validation-nonce' ),
147 ),
148 ),
149 ),
150 )
151 );
152 }
153
154 $json = array(
155 'valid' => 1,
156 'errors' => 0,
157 );
158
159 if ( acf_validate_save_post() ) {
160 wp_send_json_success( $json );
161 }
162
163 $json['valid'] = 0;
164 $json['errors'] = acf_get_validation_errors();
165
166 wp_send_json_success( $json );
167 }
168
169 /**
170 * Loops over $_POST data and validates ACF values.
171 *
172 * @since 5.4.0
173 */
174 public function acf_validate_save_post() {
175 // phpcs:disable WordPress.Security.NonceVerification.Missing -- Verified elsewhere.
176 $post_type = acf_request_arg( 'post_type', false );
177 $screen = acf_request_arg( '_acf_screen', false );
178
179 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 ) ) {
180 acf_validate_internal_post_type_values( $post_type );
181 } elseif ( acf_request_arg( 'acf_ui_options_page' ) ) {
182 acf_validate_internal_post_type_values( 'acf-ui-options-page' );
183 } else {
184 // Bail early if no matching $_POST.
185 if ( empty( $_POST['acf'] ) ) {
186 return;
187 }
188
189 acf_validate_values( $_POST['acf'], 'acf' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
190 }
191 // phpcs:enable WordPress.Security.NonceVerification.Missing
192 }
193 }
194
195 // initialize
196 acf()->validation = new acf_validation();
197 endif; // class_exists check
198
199
200 /**
201 * Public functions
202 *
203 * alias of acf()->validation->function()
204 *
205 * @type function
206 * @date 6/10/13
207 * @since 5.0.0
208 *
209 * @param n/a
210 * @return n/a
211 */
212 function acf_add_validation_error( $input, $message = '' ) {
213
214 return acf()->validation->add_error( $input, $message );
215 }
216
217 function acf_get_validation_errors() {
218
219 return acf()->validation->get_errors();
220 }
221
222 function acf_get_validation_error() {
223
224 return acf()->validation->get_error( $input );
225 }
226
227 function acf_reset_validation_errors() {
228
229 return acf()->validation->reset_errors();
230 }
231
232
233 /**
234 * This function will validate $_POST data and add errors
235 *
236 * @type function
237 * @date 25/11/2013
238 * @since 5.0.0
239 *
240 * @param $show_errors (boolean) if true, errors will be shown via a wp_die screen
241 * @return (boolean)
242 */
243 function acf_validate_save_post( $show_errors = false ) {
244
245 // action
246 do_action( 'acf/validate_save_post' );
247
248 // vars
249 $errors = acf_get_validation_errors();
250
251 // bail early if no errors
252 if ( ! $errors ) {
253 return true;
254 }
255
256 // show errors
257 if ( $show_errors ) {
258 $message = '<h2>' . __( 'Validation failed', 'acf' ) . '</h2>';
259 $message .= '<ul>';
260 foreach ( $errors as $error ) {
261 $message .= '<li>' . $error['message'] . '</li>';
262 }
263 $message .= '</ul>';
264
265 // die
266 wp_die( acf_esc_html( $message ), esc_html__( 'Validation failed', 'acf' ) );
267 }
268
269 // return
270 return false;
271 }
272
273
274 /**
275 * This function will validate an array of field values
276 *
277 * @type function
278 * @date 6/10/13
279 * @since 5.0.0
280 *
281 * @param values (array)
282 * @param $input_prefix (string)
283 * @return n/a
284 */
285 function acf_validate_values( $values, $input_prefix = '' ) {
286
287 // bail early if empty
288 if ( empty( $values ) ) {
289 return;
290 }
291
292 // loop
293 foreach ( $values as $key => $value ) {
294
295 // vars
296 $field = acf_get_field( $key );
297 $input = $input_prefix . '[' . $key . ']';
298
299 // bail early if not found
300 if ( ! $field ) {
301 continue;
302 }
303
304 // validate
305 acf_validate_value( $value, $field, $input );
306 }
307 }
308
309
310 /**
311 * This function will validate a field's value
312 *
313 * @type function
314 * @date 6/10/13
315 * @since 5.0.0
316 *
317 * @param n/a
318 * @return n/a
319 */
320 function acf_validate_value( $value, $field, $input ) {
321
322 // vars
323 $valid = true;
324 $message = sprintf( __( '%s value is required', 'acf' ), $field['label'] );
325
326 // valid
327 if ( $field['required'] ) {
328
329 // valid is set to false if the value is empty, but allow 0 as a valid value
330 if ( empty( $value ) && ! is_numeric( $value ) ) {
331 $valid = false;
332 }
333 }
334
335 /**
336 * Filters whether the value is valid.
337 *
338 * @date 28/09/13
339 * @since 5.0.0
340 *
341 * @param bool $valid The valid status. Return a string to display a custom error message.
342 * @param mixed $value The value.
343 * @param array $field The field array.
344 * @param string $input The input element's name attribute.
345 */
346 $valid = apply_filters( "acf/validate_value/type={$field['type']}", $valid, $value, $field, $input );
347 $valid = apply_filters( "acf/validate_value/name={$field['_name']}", $valid, $value, $field, $input );
348 $valid = apply_filters( "acf/validate_value/key={$field['key']}", $valid, $value, $field, $input );
349 $valid = apply_filters( 'acf/validate_value', $valid, $value, $field, $input );
350
351 // allow $valid to be a custom error message
352 if ( ! empty( $valid ) && is_string( $valid ) ) {
353 $message = $valid;
354 $valid = false;
355 }
356
357 if ( ! $valid ) {
358 acf_add_validation_error( $input, $message );
359 return false;
360 }
361
362 // return
363 return true;
364 }
365