PluginProbe ʕ •ᴥ•ʔ
Advanced Custom Fields (ACF®) / 6.8.7
Advanced Custom Fields (ACF®) v6.8.7
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 / acf-value-functions.php
advanced-custom-fields / includes Last commit date
admin 1 month ago ajax 3 months ago api 4 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
acf-value-functions.php
407 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 // Register store.
13 acf_register_store( 'values' )->prop( 'multisite', true );
14
15 /**
16 * acf_get_reference
17 *
18 * Retrieves the field key for a given field name and post_id.
19 *
20 * @date 26/1/18
21 * @since 5.6.5
22 *
23 * @param string $field_name The name of the field. eg 'sub_heading'.
24 * @param mixed $post_id The post_id of which the value is saved against.
25 * @return string|null The field key, or null on failure.
26 */
27 function acf_get_reference( $field_name, $post_id ) {
28 // Allow filter to short-circuit load_value logic.
29 $reference = apply_filters( 'acf/pre_load_reference', null, $field_name, $post_id );
30 if ( $reference !== null ) {
31 return $reference;
32 }
33
34 // Back-compat.
35 $reference = apply_filters( 'acf/pre_load_metadata', null, $post_id, $field_name, true );
36 if ( $reference !== null ) {
37 return ( $reference === '__return_null' ) ? null : $reference;
38 }
39
40 $decoded = acf_decode_post_id( $post_id );
41
42 // Bail if no ID or type.
43 if ( empty( $decoded['id'] ) || empty( $decoded['type'] ) ) {
44 return null;
45 }
46
47 $meta_instance = acf_get_meta_instance( $decoded['type'] );
48 if ( ! $meta_instance ) {
49 return null;
50 }
51
52 // Get hidden meta for this field name.
53 $reference = $meta_instance->get_reference( $decoded['id'], $field_name );
54
55 /**
56 * Filters the reference value.
57 *
58 * @date 25/1/19
59 * @since 5.7.11
60 *
61 * @param string $reference The reference value.
62 * @param string $field_name The field name.
63 * @param (int|string) $post_id The post ID where meta is stored.
64 */
65 return apply_filters( 'acf/load_reference', $reference, $field_name, $post_id );
66 }
67
68 /**
69 * Retrieves the value for a given field and post_id.
70 *
71 * @date 28/09/13
72 * @since 5.0.0
73 *
74 * @param integer|string $post_id The post id.
75 * @param array $field The field array.
76 * @return mixed
77 */
78 function acf_get_value( $post_id, $field ) {
79
80 // Allow filter to short-circuit load_value logic.
81 $value = apply_filters( 'acf/pre_load_value', null, $post_id, $field );
82 if ( $value !== null ) {
83 return $value;
84 }
85
86 // Get field name.
87 $field_name = $field['name'];
88
89 // Get field ID & type.
90 $decoded = acf_decode_post_id( $post_id );
91
92 $allow_load = true;
93
94 // If we don't have a proper field array, the field doesn't exist currently.
95 if ( empty( $field['type'] ) && empty( $field['key'] ) ) {
96
97 // Check if we should trigger warning about accessing fields too early via action.
98 do_action( 'acf/get_invalid_field_value', $field, __FUNCTION__ );
99
100 if ( apply_filters( 'acf/prevent_access_to_unknown_fields', false ) || ( 'option' === $decoded['type'] && 'options' !== $decoded['id'] ) ) {
101 $allow_load = false;
102 }
103 }
104
105 // If we're using a non options_ option key, ensure we have a valid reference key.
106 if ( 'option' === $decoded['type'] && 'options' !== $decoded['id'] ) {
107 // TODO: Move this into options meta class? i.e. return false
108 $meta = acf_get_metadata_by_field( $post_id, $field, true );
109
110 if ( ! $meta ) {
111 $allow_load = false;
112 } elseif ( $meta !== $field['key'] ) {
113 if ( ! isset( $field['__key'] ) || $meta !== $field['__key'] ) {
114 $allow_load = false;
115 }
116 }
117 }
118
119 // Load Store.
120 $store = acf_get_store( 'values' );
121
122 // If we're allowing load, check the store or load value from database.
123 if ( $allow_load ) {
124 if ( $store->has( "$post_id:$field_name" ) ) {
125 return $store->get( "$post_id:$field_name" );
126 }
127
128 $value = acf_get_metadata_by_field( $post_id, $field );
129 }
130
131 // Use field's default_value if no meta was found.
132 if ( $value === null && isset( $field['default_value'] ) ) {
133 $value = $field['default_value'];
134 }
135
136 /**
137 * Filters the $value after it has been loaded.
138 *
139 * @date 28/09/13
140 * @since 5.0.0
141 *
142 * @param mixed $value The value to preview.
143 * @param string $post_id The post ID for this value.
144 * @param array $field The field array.
145 */
146 $value = apply_filters( 'acf/load_value', $value, $post_id, $field );
147
148 // Update store if we allowed the value load.
149 if ( $allow_load ) {
150 $store->set( "$post_id:$field_name", $value );
151 }
152
153 // Return value.
154 return $value;
155 }
156
157 // Register variation.
158 acf_add_filter_variations( 'acf/load_value', array( 'type', 'name', 'key' ), 2 );
159
160 /**
161 * Returns a formatted version of the provided value.
162 *
163 * @since 5.0.0
164 *
165 * @param mixed $value The field value.
166 * @param integer|string $post_id The post id.
167 * @param array $field The field array.
168 * @param boolean $escape_html Ask the field for a HTML safe version of it's output.
169 *
170 * @return mixed
171 */
172 function acf_format_value( $value, $post_id, $field, $escape_html = false ) {
173
174 // Allow filter to short-circuit load_value logic.
175 $check = apply_filters( 'acf/pre_format_value', null, $value, $post_id, $field, $escape_html );
176 if ( $check !== null ) {
177 return $check;
178 }
179
180 // Get field name.
181 $field_name = $field['name'];
182 $cache_name = $escape_html ? "$post_id:$field_name:escaped" : "$post_id:$field_name:formatted";
183
184 // Check store.
185 $store = acf_get_store( 'values' );
186 if ( $store->has( $cache_name ) ) {
187 return $store->get( $cache_name );
188 }
189
190 /**
191 * Filters the $value for use in a template function.
192 *
193 * @since 5.0.0
194 *
195 * @param mixed $value The value to preview.
196 * @param string $post_id The post ID for this value.
197 * @param array $field The field array.
198 * @param boolean $escape_html Ask the field for a HTML safe version of it's output.
199 */
200 $value = apply_filters( 'acf/format_value', $value, $post_id, $field, $escape_html );
201
202 // Update store.
203 $store->set( $cache_name, $value );
204
205 // Return value.
206 return $value;
207 }
208
209 // Register variation.
210 acf_add_filter_variations( 'acf/format_value', array( 'type', 'name', 'key' ), 2 );
211
212 /**
213 * acf_update_value
214 *
215 * Updates the value for a given field and post_id.
216 *
217 * @date 28/09/13
218 * @since 5.0.0
219 *
220 * @param mixed $value The new value.
221 * @param (int|string) $post_id The post id.
222 * @param array $field The field array.
223 * @return boolean
224 */
225 function acf_update_value( $value, $post_id, $field ) {
226
227 // Allow filter to short-circuit update_value logic.
228 $check = apply_filters( 'acf/pre_update_value', null, $value, $post_id, $field );
229 if ( $check !== null ) {
230 return $check;
231 }
232
233 /**
234 * Filters the $value before it is updated.
235 *
236 * @date 28/09/13
237 * @since 5.0.0
238 *
239 * @param mixed $value The value to update.
240 * @param string $post_id The post ID for this value.
241 * @param array $field The field array.
242 * @param mixed $original The original value before modification.
243 */
244 $value = apply_filters( 'acf/update_value', $value, $post_id, $field, $value );
245
246 // Allow null to delete value.
247 if ( $value === null ) {
248 return acf_delete_value( $post_id, $field );
249 }
250
251 // Update value and reference key.
252 $return = acf_update_metadata_by_field( $post_id, $field, $value );
253 acf_update_metadata_by_field( $post_id, $field, $field['key'], true );
254
255 // Delete stored data.
256 acf_flush_value_cache( $post_id, $field['name'] );
257
258 // Return update status.
259 return $return;
260 }
261
262 // Register variation.
263 acf_add_filter_variations( 'acf/update_value', array( 'type', 'name', 'key' ), 2 );
264
265 /**
266 * acf_update_values
267 *
268 * Updates an array of values.
269 *
270 * @date 26/2/19
271 * @since 5.7.13
272 *
273 * @param array values The array of values.
274 * @param (int|string) $post_id The post id.
275 * @return void
276 */
277 function acf_update_values( $values, $post_id ) {
278
279 // Loop over values.
280 foreach ( $values as $key => $value ) {
281
282 // Get field.
283 $field = acf_get_field( $key );
284
285 // Update value.
286 if ( $field ) {
287 acf_update_value( $value, $post_id, $field );
288 }
289 }
290 }
291
292 /**
293 * acf_flush_value_cache
294 *
295 * Deletes all cached data for this value.
296 *
297 * @date 22/1/19
298 * @since 5.7.10
299 *
300 * @param (int|string) $post_id The post id.
301 * @param string $field_name The field name.
302 * @return void
303 */
304 function acf_flush_value_cache( $post_id = 0, $field_name = '' ) {
305
306 // Delete stored data.
307 acf_get_store( 'values' )
308 ->remove( "$post_id:$field_name" )
309 ->remove( "$post_id:$field_name:formatted" )
310 ->remove( "$post_id:$field_name:escaped" );
311 }
312
313 /**
314 * acf_delete_value
315 *
316 * Deletes the value for a given field and post_id.
317 *
318 * @date 28/09/13
319 * @since 5.0.0
320 *
321 * @param (int|string) $post_id The post id.
322 * @param array $field The field array.
323 * @return boolean
324 */
325 function acf_delete_value( $post_id, $field ) {
326
327 /**
328 * Fires before a value is deleted.
329 *
330 * @date 28/09/13
331 * @since 5.0.0
332 *
333 * @param string $post_id The post ID for this value.
334 * @param mixed $name The meta name.
335 * @param array $field The field array.
336 */
337 do_action( 'acf/delete_value', $post_id, $field['name'], $field );
338
339 // Delete value and reference key.
340 $return = acf_delete_metadata_by_field( $post_id, $field );
341 acf_delete_metadata_by_field( $post_id, $field, true );
342
343 // Delete stored data.
344 acf_flush_value_cache( $post_id, $field['name'] );
345
346 // Return delete status.
347 return $return;
348 }
349
350 // Register variation.
351 acf_add_filter_variations( 'acf/delete_value', array( 'type', 'name', 'key' ), 2 );
352
353 /**
354 * acf_preview_value
355 *
356 * Return a human friendly 'preview' for a given field value.
357 *
358 * @date 28/09/13
359 * @since 5.0.0
360 *
361 * @param mixed $value The new value.
362 * @param (int|string) $post_id The post id.
363 * @param array $field The field array.
364 * @return boolean
365 */
366 function acf_preview_value( $value, $post_id, $field ) {
367
368 /**
369 * Filters the $value before used in HTML.
370 *
371 * @date 24/10/16
372 * @since 5.5.0
373 *
374 * @param mixed $value The value to preview.
375 * @param string $post_id The post ID for this value.
376 * @param array $field The field array.
377 */
378 return apply_filters( 'acf/preview_value', $value, $post_id, $field );
379 }
380
381 // Register variation.
382 acf_add_filter_variations( 'acf/preview_value', array( 'type', 'name', 'key' ), 2 );
383
384 /**
385 * Potentially log an error if a field doesn't exist when we expect it to.
386 *
387 * @param array $field An array representing the field that a value was requested for.
388 * @param string $function The function that noticed the problem.
389 *
390 * @return void
391 */
392 function acf_log_invalid_field_notice( $field, $function ) {
393 // If "init" has fired, ACF probably wasn't initialized early.
394 if ( did_action( 'init' ) ) {
395 return;
396 }
397
398 $error_text = sprintf(
399 // This happens too early for translations to be loaded properly.
400 '<strong>%1$s</strong> - We\'ve detected one or more calls to retrieve ACF field values before ACF has been initialized. This is not supported and can result in malformed or missing data. <a href="%2$s" target="_blank">Learn how to fix this</a>.',
401 acf_get_setting( 'name' ),
402 acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/acf-field-functions/', 'docs', 'early_init_warning' )
403 );
404 _doing_it_wrong( esc_html( $function ), acf_esc_html( $error_text ), '5.11.1' );
405 }
406 add_action( 'acf/get_invalid_field_value', 'acf_log_invalid_field_notice', 10, 2 );
407