PluginProbe ʕ •ᴥ•ʔ
Advanced Custom Fields (ACF®) / 6.8.8
Advanced Custom Fields (ACF®) v6.8.8
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 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.6.1 6.2.7 6.2.8 6.2.9 6.3.0 6.3.1 6.3.10.2 6.3.11 6.3.12 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.6.1 6.4.0 6.4.0.1 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.6.0 6.6.1 6.6.2 6.7.0 6.7.1 6.7.2 6.8.0 trunk 1.0.0 1.0.2 1.0.3 1.0.5 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1.1 2.1.3 2.1.4 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.6 3.0.7 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.5.7 3.5.8 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.8 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.8 4.3.9 4.4.0 4.4.1 4.4.10 4.4.11 4.4.12 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 5.10 5.10.1 5.10.2 5.11 5.11.1 5.11.2 5.11.3 5.11.4 5.12 5.12.1 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.6.10 5.6.2 5.6.3 5.6.4 5.6.5 5.6.6 5.6.7 5.6.8 5.6.9 5.7.0 5.7.1 5.7.10 5.7.12 5.7.13 5.7.2 5.7.3 5.7.4 5.7.5 5.7.6 5.7.7 5.7.8 5.7.9 5.8.0 5.8.1 5.8.10 5.8.11 5.8.12 5.8.13 5.8.14 5.8.2 5.8.3 5.8.4
advanced-custom-fields / includes / validation.php
advanced-custom-fields / includes Last commit date
admin 1 month ago ajax 3 months ago api 2 weeks ago fields 4 weeks ago forms 4 weeks ago legacy 5 months ago locations 1 month ago post-types 5 months ago rest-api 4 weeks ago walkers 5 months ago acf-bidirectional-functions.php 5 months ago acf-field-functions.php 5 months ago acf-field-group-functions.php 5 months ago acf-form-functions.php 5 months ago acf-helper-functions.php 5 months ago acf-hook-functions.php 5 months ago acf-input-functions.php 5 months ago acf-internal-post-type-functions.php 5 months ago acf-meta-functions.php 2 months ago acf-post-functions.php 5 months ago acf-post-type-functions.php 5 months ago acf-taxonomy-functions.php 5 months ago acf-user-functions.php 5 months ago acf-utility-functions.php 5 months ago acf-value-functions.php 5 months ago acf-wp-functions.php 5 months ago assets.php 5 months ago class-acf-data.php 5 months ago class-acf-internal-post-type.php 5 months ago compatibility.php 5 months ago deprecated.php 5 months ago fields.php 5 months ago index.php 2 years ago l10n.php 5 months ago local-fields.php 5 months ago local-json.php 3 months ago local-meta.php 5 months ago locations.php 5 months ago loop.php 5 months ago media.php 5 months ago rest-api.php 5 months ago revisions.php 3 months ago third-party.php 5 months ago upgrades.php 2 months ago validation.php 5 months ago wpml.php 5 months ago
validation.php
374 lines
1 <?php
2 /**
3 * @package ACF
4 * @author WP Engine
5 *
6 * © 2026 Advanced Custom Fields (ACF®). All rights reserved.
7 * "ACF" is a trademark of WP Engine.
8 * Licensed under the GNU General Public License v2 or later.
9 * https://www.gnu.org/licenses/gpl-2.0.html
10 */
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit; // Exit if accessed directly
14 }
15
16 if ( ! class_exists( 'acf_validation' ) ) :
17 class acf_validation {
18
19 /**
20 * An array of validation errors.
21 * @var array
22 */
23 public $errors = array();
24
25 /**
26 * This function will setup the class functionality
27 *
28 * @type function
29 * @date 5/03/2014
30 * @since 5.0.0
31 *
32 * @param n/a
33 * @return n/a
34 */
35 function __construct() {
36
37 // ajax
38 add_action( 'wp_ajax_acf/validate_save_post', array( $this, 'ajax_validate_save_post' ) );
39 add_action( 'wp_ajax_nopriv_acf/validate_save_post', array( $this, 'ajax_validate_save_post' ) );
40 add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 5 );
41 }
42
43
44 /**
45 * This function will add an error message for a field
46 *
47 * @type function
48 * @date 25/11/2013
49 * @since 5.0.0
50 *
51 * @param $input (string) name attribute of DOM elmenet
52 * @param $message (string) error message
53 * @return $post_id (int)
54 */
55 function add_error( $input, $message ) {
56
57 // add to array
58 $this->errors[] = array(
59 'input' => $input,
60 'message' => $message,
61 );
62 }
63
64
65 /**
66 * This function will return an error for a given input
67 *
68 * @type function
69 * @date 5/03/2016
70 * @since 5.3.2
71 *
72 * @param $input (string) name attribute of DOM elmenet
73 * @return (mixed)
74 */
75 function get_error( $input ) {
76
77 // bail early if no errors
78 if ( empty( $this->errors ) ) {
79 return false;
80 }
81
82 // loop
83 foreach ( $this->errors as $error ) {
84 if ( $error['input'] === $input ) {
85 return $error;
86 }
87 }
88
89 // return
90 return false;
91 }
92
93
94 /**
95 * This function will return validation errors
96 *
97 * @type function
98 * @date 25/11/2013
99 * @since 5.0.0
100 *
101 * @param n/a
102 * @return (array|boolean)
103 */
104 function get_errors() {
105
106 // bail early if no errors
107 if ( empty( $this->errors ) ) {
108 return false;
109 }
110
111 // return
112 return $this->errors;
113 }
114
115
116 /**
117 * This function will remove all errors
118 *
119 * @type function
120 * @date 4/03/2016
121 * @since 5.3.2
122 *
123 * @param n/a
124 * @return n/a
125 */
126 function reset_errors() {
127
128 $this->errors = array();
129 }
130
131 /**
132 * Validates $_POST data via AJAX prior to save.
133 *
134 * @since 5.0.9
135 *
136 * @return void
137 */
138 public function ajax_validate_save_post() {
139 if ( ! acf_verify_ajax() ) {
140 if ( empty( $_REQUEST['nonce'] ) ) {
141 $nonce_error = __( 'ACF was unable to perform validation because no nonce was received by the server.', 'acf' );
142 } else {
143 $nonce_error = __( 'ACF was unable to perform validation because the provided nonce failed verification.', 'acf' );
144 }
145
146 wp_send_json_success(
147 array(
148 'valid' => 0,
149 'errors' => array(
150 array(
151 'input' => false,
152 'message' => $nonce_error,
153 'action' => array(
154 'label' => __( 'Learn more', 'acf' ),
155 'url' => acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/validation-nonce-errors/', 'docs', 'validation-nonce' ),
156 ),
157 ),
158 ),
159 )
160 );
161 }
162
163 $json = array(
164 'valid' => 1,
165 'errors' => 0,
166 );
167
168 if ( acf_validate_save_post() ) {
169 wp_send_json_success( $json );
170 }
171
172 $json['valid'] = 0;
173 $json['errors'] = acf_get_validation_errors();
174
175 wp_send_json_success( $json );
176 }
177
178 /**
179 * Loops over $_POST data and validates ACF values.
180 *
181 * @since 5.4.0
182 */
183 public function acf_validate_save_post() {
184 // phpcs:disable WordPress.Security.NonceVerification.Missing -- Verified elsewhere.
185 $post_type = acf_request_arg( 'post_type', false );
186 $screen = acf_request_arg( '_acf_screen', false );
187
188 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 ) ) {
189 acf_validate_internal_post_type_values( $post_type );
190 } elseif ( acf_request_arg( 'acf_ui_options_page' ) ) {
191 acf_validate_internal_post_type_values( 'acf-ui-options-page' );
192 } else {
193 // Bail early if no matching $_POST.
194 if ( empty( $_POST['acf'] ) ) {
195 return;
196 }
197
198 acf_validate_values( $_POST['acf'], 'acf' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
199 }
200 // phpcs:enable WordPress.Security.NonceVerification.Missing
201 }
202 }
203
204 // initialize
205 acf()->validation = new acf_validation();
206 endif; // class_exists check
207
208
209 /**
210 * Public functions
211 *
212 * alias of acf()->validation->function()
213 *
214 * @type function
215 * @date 6/10/13
216 * @since 5.0.0
217 *
218 * @param n/a
219 * @return n/a
220 */
221 function acf_add_validation_error( $input, $message = '' ) {
222
223 return acf()->validation->add_error( $input, $message );
224 }
225
226 function acf_get_validation_errors() {
227
228 return acf()->validation->get_errors();
229 }
230
231 function acf_get_validation_error() {
232
233 return acf()->validation->get_error( $input );
234 }
235
236 function acf_reset_validation_errors() {
237
238 return acf()->validation->reset_errors();
239 }
240
241
242 /**
243 * This function will validate $_POST data and add errors
244 *
245 * @type function
246 * @date 25/11/2013
247 * @since 5.0.0
248 *
249 * @param $show_errors (boolean) if true, errors will be shown via a wp_die screen
250 * @return (boolean)
251 */
252 function acf_validate_save_post( $show_errors = false ) {
253
254 // action
255 do_action( 'acf/validate_save_post' );
256
257 // vars
258 $errors = acf_get_validation_errors();
259
260 // bail early if no errors
261 if ( ! $errors ) {
262 return true;
263 }
264
265 // show errors
266 if ( $show_errors ) {
267 $message = '<h2>' . __( 'Validation failed', 'acf' ) . '</h2>';
268 $message .= '<ul>';
269 foreach ( $errors as $error ) {
270 $message .= '<li>' . $error['message'] . '</li>';
271 }
272 $message .= '</ul>';
273
274 // die
275 wp_die( acf_esc_html( $message ), esc_html__( 'Validation failed', 'acf' ) );
276 }
277
278 // return
279 return false;
280 }
281
282
283 /**
284 * This function will validate an array of field values
285 *
286 * @type function
287 * @date 6/10/13
288 * @since 5.0.0
289 *
290 * @param values (array)
291 * @param $input_prefix (string)
292 * @return n/a
293 */
294 function acf_validate_values( $values, $input_prefix = '' ) {
295
296 // bail early if empty
297 if ( empty( $values ) ) {
298 return;
299 }
300
301 // loop
302 foreach ( $values as $key => $value ) {
303
304 // vars
305 $field = acf_get_field( $key );
306 $input = $input_prefix . '[' . $key . ']';
307
308 // bail early if not found
309 if ( ! $field ) {
310 continue;
311 }
312
313 // validate
314 acf_validate_value( $value, $field, $input );
315 }
316 }
317
318
319 /**
320 * This function will validate a field's value
321 *
322 * @type function
323 * @date 6/10/13
324 * @since 5.0.0
325 *
326 * @param n/a
327 * @return n/a
328 */
329 function acf_validate_value( $value, $field, $input ) {
330
331 // vars
332 $valid = true;
333 $message = sprintf( __( '%s value is required', 'acf' ), $field['label'] );
334
335 // valid
336 if ( $field['required'] ) {
337
338 // valid is set to false if the value is empty, but allow 0 as a valid value
339 if ( empty( $value ) && ! is_numeric( $value ) ) {
340 $valid = false;
341 }
342 }
343
344 /**
345 * Filters whether the value is valid.
346 *
347 * @date 28/09/13
348 * @since 5.0.0
349 *
350 * @param bool $valid The valid status. Return a string to display a custom error message.
351 * @param mixed $value The value.
352 * @param array $field The field array.
353 * @param string $input The input element's name attribute.
354 */
355 $valid = apply_filters( "acf/validate_value/type={$field['type']}", $valid, $value, $field, $input );
356 $valid = apply_filters( "acf/validate_value/name={$field['_name']}", $valid, $value, $field, $input );
357 $valid = apply_filters( "acf/validate_value/key={$field['key']}", $valid, $value, $field, $input );
358 $valid = apply_filters( 'acf/validate_value', $valid, $value, $field, $input );
359
360 // allow $valid to be a custom error message
361 if ( ! empty( $valid ) && is_string( $valid ) ) {
362 $message = $valid;
363 $valid = false;
364 }
365
366 if ( ! $valid ) {
367 acf_add_validation_error( $input, $message );
368 return false;
369 }
370
371 // return
372 return true;
373 }
374