1111 * @return array
1212 */
1313function acf_get_meta ( $ post_id = 0 ) {
14-
1514 // Allow filter to short-circuit load_value logic.
1615 $ null = apply_filters ( 'acf/pre_load_meta ' , null , $ post_id );
1716 if ( $ null !== null ) {
1817 return ( $ null === '__return_null ' ) ? null : $ null ;
1918 }
2019
21- // Decode $post_id for $type and $id.
22- $ decoded = acf_decode_post_id ( $ post_id );
20+ // Decode the $post_id for $type and $id.
21+ $ decoded = acf_decode_post_id ( $ post_id );
22+ $ instance = acf_get_meta_instance ( $ decoded ['type ' ] );
23+ $ meta = array ();
2324
24- /**
25- * Determine CRUD function.
26- *
27- * - Relies on decoded post_id result to identify option or meta types.
28- * - Uses xxx_metadata(type) instead of xxx_type_meta() to bypass additional logic that could alter the ID.
29- */
30- if ( $ decoded ['type ' ] === 'option ' ) {
31- $ allmeta = acf_get_option_meta ( $ decoded ['id ' ] );
32- } else {
33- $ allmeta = get_metadata ( $ decoded ['type ' ], $ decoded ['id ' ], '' );
25+ if ( $ instance ) {
26+ $ meta = $ instance ->get_meta ( $ decoded ['id ' ] );
3427 }
3528
36- // Loop over meta and check that a reference exists for each value.
37- $ meta = array ();
38- if ( $ allmeta ) {
39- foreach ( $ allmeta as $ key => $ value ) {
40-
41- // If a reference exists for this value, add it to the meta array.
42- if ( isset ( $ allmeta [ "_ $ key " ] ) ) {
43- $ meta [ $ key ] = $ allmeta [ $ key ][0 ];
44- $ meta [ "_ $ key " ] = $ allmeta [ "_ $ key " ][0 ];
45- }
46- }
47- }
48-
49- // Unserialized results (get_metadata does not unserialize if $key is empty).
50- $ meta = array_map ( 'acf_maybe_unserialize ' , $ meta );
51-
5229 /**
5330 * Filters the $meta array after it has been loaded.
5431 *
@@ -74,7 +51,6 @@ function acf_get_meta( $post_id = 0 ) {
7451 * @return array
7552 */
7653function acf_get_option_meta ( $ prefix = '' ) {
77-
7854 // Globals.
7955 global $ wpdb ;
8056
@@ -241,32 +217,23 @@ function acf_delete_metadata( $post_id = 0, $name = '', $hidden = false ) {
241217}
242218
243219/**
244- * acf_copy_postmeta
245- *
246220 * Copies meta from one post to another. Useful for saving and restoring revisions.
247221 *
248- * @date 25/06/2016
249222 * @since 5.3.8
250223 *
251- * @param (int |string) $from_post_id The post id to copy from.
252- * @param (int |string) $to_post_id The post id to paste to.
253- * @return void
224+ * @param integer |string $from_post_id The post id to copy from.
225+ * @param integer |string $to_post_id The post id to paste to.
226+ * @return void
254227 */
255228function acf_copy_metadata ( $ from_post_id = 0 , $ to_post_id = 0 ) {
256-
257- // Get all postmeta.
229+ // Get all metadata.
258230 $ meta = acf_get_meta ( $ from_post_id );
259231
260- // Check meta.
261- if ( $ meta ) {
262-
263- // Slash data. WP expects all data to be slashed and will unslash it (fixes '\' character issues).
264- $ meta = wp_slash ( $ meta );
232+ $ decoded = acf_decode_post_id ( $ to_post_id );
233+ $ instance = acf_get_meta_instance ( $ decoded ['type ' ] );
265234
266- // Loop over meta.
267- foreach ( $ meta as $ name => $ value ) {
268- acf_update_metadata ( $ to_post_id , $ name , $ value );
269- }
235+ if ( $ meta && $ instance ) {
236+ $ instance ->update_meta ( $ decoded ['id ' ], $ meta );
270237 }
271238}
272239
@@ -382,3 +349,155 @@ function acf_update_metaref( $post_id = 0, $type = 'fields', $references = array
382349 // Update metadata.
383350 return acf_update_metadata ( $ post_id , "_acf_ $ type " , $ references );
384351}
352+
353+ /**
354+ * Retrieves an ACF meta instance for the provided meta type.
355+ *
356+ * @since 6.4
357+ *
358+ * @param string $type The meta type as decoded from the post ID.
359+ * @return object|null
360+ */
361+ function acf_get_meta_instance ( string $ type ): ?object {
362+ $ instance = null ;
363+ $ meta_locations = acf_get_store ( 'acf-meta-locations ' );
364+
365+ if ( $ meta_locations && $ meta_locations ->has ( $ type ) ) {
366+ $ instance = acf_get_instance ( $ meta_locations ->get ( $ type ) );
367+ }
368+
369+ return $ instance ;
370+ }
371+
372+ /**
373+ * Gets metadata from the database.
374+ *
375+ * @since 6.4
376+ *
377+ * @param integer|string $post_id The post id.
378+ * @param array $field The field array.
379+ * @param boolean $hidden True if we should return the reference key.
380+ * @return mixed
381+ */
382+ function acf_get_metadata_by_field ( $ post_id = 0 , $ field = array (), bool $ hidden = false ) {
383+ if ( empty ( $ field ['name ' ] ) ) {
384+ return null ;
385+ }
386+
387+ // Allow filter to short-circuit logic.
388+ $ null = apply_filters ( 'acf/pre_load_metadata ' , null , $ post_id , $ field ['name ' ], $ hidden );
389+ if ( $ null !== null ) {
390+ return ( $ null === '__return_null ' ) ? null : $ null ;
391+ }
392+
393+ // Decode the $post_id for $type and $id.
394+ $ decoded = acf_decode_post_id ( $ post_id );
395+ $ id = $ decoded ['id ' ];
396+ $ type = $ decoded ['type ' ];
397+
398+ // Bail early if no $id (possible during new acf_form).
399+ if ( ! $ id ) {
400+ return null ;
401+ }
402+
403+ $ meta_instance = acf_get_meta_instance ( $ type );
404+
405+ if ( ! $ meta_instance ) {
406+ return false ;
407+ }
408+
409+ if ( $ hidden ) {
410+ return $ meta_instance ->get_reference ( $ id , $ field ['name ' ] );
411+ }
412+
413+ return $ meta_instance ->get_value ( $ id , $ field );
414+ }
415+
416+ /**
417+ * Updates metadata in the database.
418+ *
419+ * @since 6.4
420+ *
421+ * @param integer|string $post_id The post id.
422+ * @param array $field The field array.
423+ * @param mixed $value The meta value.
424+ * @param boolean $hidden True if we should update the reference key.
425+ * @return integer|boolean Meta ID if the key didn't exist, true on successful update, false on failure.
426+ */
427+ function acf_update_metadata_by_field ( $ post_id = 0 , $ field = array (), $ value = '' , bool $ hidden = false ) {
428+ if ( empty ( $ field ['name ' ] ) ) {
429+ return null ;
430+ }
431+
432+ // Allow filter to short-circuit logic.
433+ $ pre = apply_filters ( 'acf/pre_update_metadata ' , null , $ post_id , $ field ['name ' ], $ value , $ hidden );
434+ if ( $ pre !== null ) {
435+ return $ pre ;
436+ }
437+
438+ // Decode the $post_id for $type and $id.
439+ $ decoded = acf_decode_post_id ( $ post_id );
440+ $ id = $ decoded ['id ' ];
441+ $ type = $ decoded ['type ' ];
442+
443+ // Bail early if no $id (possible during new acf_form).
444+ if ( ! $ id ) {
445+ return false ;
446+ }
447+
448+ $ meta_instance = acf_get_meta_instance ( $ type );
449+
450+ if ( ! $ meta_instance ) {
451+ return false ;
452+ }
453+
454+ if ( $ hidden ) {
455+ return $ meta_instance ->update_reference ( $ id , $ field ['name ' ], $ field ['key ' ] );
456+ }
457+
458+ return $ meta_instance ->update_value ( $ id , $ field , $ value );
459+ }
460+
461+ /**
462+ * Deletes metadata from the database.
463+ *
464+ * @since 6.4
465+ *
466+ * @param integer|string $post_id The post id.
467+ * @param array $field The field array.
468+ * @param boolean $hidden True if we should update the reference key.
469+ * @return boolean
470+ */
471+ function acf_delete_metadata_by_field ( $ post_id = 0 , $ field = array (), bool $ hidden = false ) {
472+ if ( empty ( $ field ['name ' ] ) ) {
473+ return null ;
474+ }
475+
476+ // Allow filter to short-circuit logic.
477+ $ pre = apply_filters ( 'acf/pre_delete_metadata ' , null , $ post_id , $ field ['name ' ], $ hidden );
478+ if ( $ pre !== null ) {
479+ return $ pre ;
480+ }
481+
482+ // Decode the $post_id for $type and $id.
483+ $ decoded = acf_decode_post_id ( $ post_id );
484+ $ id = $ decoded ['id ' ];
485+ $ type = $ decoded ['type ' ];
486+
487+ // Bail early if no $id (possible during new acf_form).
488+ if ( ! $ id ) {
489+ return false ;
490+ }
491+
492+ $ meta_instance = acf_get_meta_instance ( $ type );
493+
494+ if ( ! $ meta_instance ) {
495+ return false ;
496+ }
497+
498+ if ( $ hidden ) {
499+ return $ meta_instance ->delete_reference ( $ id , $ field ['name ' ] );
500+ }
501+
502+ return $ meta_instance ->delete_value ( $ id , $ field );
503+ }
0 commit comments