385 lines
10 KiB
PHP
385 lines
10 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* Returns an array of "ACF only" meta for the given post_id.
|
||
|
*
|
||
|
* @date 9/10/18
|
||
|
* @since 5.8.0
|
||
|
*
|
||
|
* @param mixed $post_id The post_id for this data.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
function acf_get_meta( $post_id = 0 ) {
|
||
|
|
||
|
// Allow filter to short-circuit load_value logic.
|
||
|
$null = apply_filters( 'acf/pre_load_meta', null, $post_id );
|
||
|
if ( $null !== null ) {
|
||
|
return ( $null === '__return_null' ) ? null : $null;
|
||
|
}
|
||
|
|
||
|
// Decode $post_id for $type and $id.
|
||
|
$decoded = acf_decode_post_id( $post_id );
|
||
|
|
||
|
/**
|
||
|
* Determine CRUD function.
|
||
|
*
|
||
|
* - Relies on decoded post_id result to identify option or meta types.
|
||
|
* - Uses xxx_metadata(type) instead of xxx_type_meta() to bypass additional logic that could alter the ID.
|
||
|
*/
|
||
|
if ( $decoded['type'] === 'option' ) {
|
||
|
$allmeta = acf_get_option_meta( $decoded['id'] );
|
||
|
} else {
|
||
|
$allmeta = get_metadata( $decoded['type'], $decoded['id'], '' );
|
||
|
}
|
||
|
|
||
|
// Loop over meta and check that a reference exists for each value.
|
||
|
$meta = array();
|
||
|
if ( $allmeta ) {
|
||
|
foreach ( $allmeta as $key => $value ) {
|
||
|
|
||
|
// If a reference exists for this value, add it to the meta array.
|
||
|
if ( isset( $allmeta[ "_$key" ] ) ) {
|
||
|
$meta[ $key ] = $allmeta[ $key ][0];
|
||
|
$meta[ "_$key" ] = $allmeta[ "_$key" ][0];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Unserialized results (get_metadata does not unserialize if $key is empty).
|
||
|
$meta = array_map( 'acf_maybe_unserialize', $meta );
|
||
|
|
||
|
/**
|
||
|
* Filters the $meta array after it has been loaded.
|
||
|
*
|
||
|
* @date 25/1/19
|
||
|
* @since 5.7.11
|
||
|
*
|
||
|
* @param array $meta The array of loaded meta.
|
||
|
* @param string $post_id The $post_id for this meta.
|
||
|
*/
|
||
|
return apply_filters( 'acf/load_meta', $meta, $post_id );
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* acf_get_option_meta
|
||
|
*
|
||
|
* Returns an array of meta for the given wp_option name prefix in the same format as get_post_meta().
|
||
|
*
|
||
|
* @date 9/10/18
|
||
|
* @since 5.8.0
|
||
|
*
|
||
|
* @param string $prefix The wp_option name prefix.
|
||
|
* @return array
|
||
|
*/
|
||
|
function acf_get_option_meta( $prefix = '' ) {
|
||
|
|
||
|
// Globals.
|
||
|
global $wpdb;
|
||
|
|
||
|
// Vars.
|
||
|
$meta = array();
|
||
|
$search = "{$prefix}_%";
|
||
|
$_search = "_{$prefix}_%";
|
||
|
|
||
|
// Escape underscores for LIKE.
|
||
|
$search = str_replace( '_', '\_', $search );
|
||
|
$_search = str_replace( '_', '\_', $_search );
|
||
|
|
||
|
// Query database for results.
|
||
|
$rows = $wpdb->get_results(
|
||
|
$wpdb->prepare(
|
||
|
"SELECT *
|
||
|
FROM $wpdb->options
|
||
|
WHERE option_name LIKE %s
|
||
|
OR option_name LIKE %s",
|
||
|
$search,
|
||
|
$_search
|
||
|
),
|
||
|
ARRAY_A
|
||
|
);
|
||
|
|
||
|
// Loop over results and append meta (removing the $prefix from the option name).
|
||
|
$len = strlen( "{$prefix}_" );
|
||
|
foreach ( $rows as $row ) {
|
||
|
$meta[ substr( $row['option_name'], $len ) ][] = $row['option_value'];
|
||
|
}
|
||
|
|
||
|
// Return results.
|
||
|
return $meta;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Retrieves specific metadata from the database.
|
||
|
*
|
||
|
* @date 16/10/2015
|
||
|
* @since 5.2.3
|
||
|
*
|
||
|
* @param int|string $post_id The post id.
|
||
|
* @param string $name The meta name.
|
||
|
* @param bool $hidden If the meta is hidden (starts with an underscore).
|
||
|
*
|
||
|
* @return mixed
|
||
|
*/
|
||
|
function acf_get_metadata( $post_id = 0, $name = '', $hidden = false ) {
|
||
|
// Allow filter to short-circuit logic.
|
||
|
$null = apply_filters( 'acf/pre_load_metadata', null, $post_id, $name, $hidden );
|
||
|
if ( $null !== null ) {
|
||
|
return ( $null === '__return_null' ) ? null : $null;
|
||
|
}
|
||
|
|
||
|
// Decode $post_id for $type and $id.
|
||
|
$decoded = acf_decode_post_id( $post_id );
|
||
|
$id = $decoded['id'];
|
||
|
$type = $decoded['type'];
|
||
|
|
||
|
// Hidden meta uses an underscore prefix.
|
||
|
$prefix = $hidden ? '_' : '';
|
||
|
|
||
|
// Bail early if no $id (possible during new acf_form).
|
||
|
if ( ! $id ) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
// Determine CRUD function.
|
||
|
// - Relies on decoded post_id result to identify option or meta types.
|
||
|
// - Uses xxx_metadata(type) instead of xxx_type_meta() to bypass additional logic that could alter the ID.
|
||
|
if ( $type === 'option' ) {
|
||
|
return get_option( "{$prefix}{$id}_{$name}", null );
|
||
|
} else {
|
||
|
$meta = get_metadata( $type, $id, "{$prefix}{$name}", false );
|
||
|
return isset( $meta[0] ) ? $meta[0] : null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Updates metadata in the database.
|
||
|
*
|
||
|
* @date 16/10/2015
|
||
|
* @since 5.2.3
|
||
|
*
|
||
|
* @param int|string $post_id The post id.
|
||
|
* @param string $name The meta name.
|
||
|
* @param mixed $value The meta value.
|
||
|
* @param bool $hidden If the meta is hidden (starts with an underscore).
|
||
|
*
|
||
|
* @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
|
||
|
*/
|
||
|
function acf_update_metadata( $post_id = 0, $name = '', $value = '', $hidden = false ) {
|
||
|
// Allow filter to short-circuit logic.
|
||
|
$pre = apply_filters( 'acf/pre_update_metadata', null, $post_id, $name, $value, $hidden );
|
||
|
if ( $pre !== null ) {
|
||
|
return $pre;
|
||
|
}
|
||
|
|
||
|
// Decode $post_id for $type and $id.
|
||
|
$decoded = acf_decode_post_id( $post_id );
|
||
|
$id = $decoded['id'];
|
||
|
$type = $decoded['type'];
|
||
|
|
||
|
// Hidden meta uses an underscore prefix.
|
||
|
$prefix = $hidden ? '_' : '';
|
||
|
|
||
|
// Bail early if no $id (possible during new acf_form).
|
||
|
if ( ! $id ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Determine CRUD function.
|
||
|
// - Relies on decoded post_id result to identify option or meta types.
|
||
|
// - Uses xxx_metadata(type) instead of xxx_type_meta() to bypass additional logic that could alter the ID.
|
||
|
if ( $type === 'option' ) {
|
||
|
$value = wp_unslash( $value );
|
||
|
$autoload = (bool) acf_get_setting( 'autoload' );
|
||
|
return update_option( "{$prefix}{$id}_{$name}", $value, $autoload );
|
||
|
} else {
|
||
|
return update_metadata( $type, $id, "{$prefix}{$name}", $value );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Deletes metadata from the database.
|
||
|
*
|
||
|
* @date 16/10/2015
|
||
|
* @since 5.2.3
|
||
|
*
|
||
|
* @param int|string $post_id The post id.
|
||
|
* @param string $name The meta name.
|
||
|
* @param bool $hidden If the meta is hidden (starts with an underscore).
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
function acf_delete_metadata( $post_id = 0, $name = '', $hidden = false ) {
|
||
|
// Allow filter to short-circuit logic.
|
||
|
$pre = apply_filters( 'acf/pre_delete_metadata', null, $post_id, $name, $hidden );
|
||
|
if ( $pre !== null ) {
|
||
|
return $pre;
|
||
|
}
|
||
|
|
||
|
// Decode $post_id for $type and $id.
|
||
|
$decoded = acf_decode_post_id( $post_id );
|
||
|
$id = $decoded['id'];
|
||
|
$type = $decoded['type'];
|
||
|
|
||
|
// Hidden meta uses an underscore prefix.
|
||
|
$prefix = $hidden ? '_' : '';
|
||
|
|
||
|
// Bail early if no $id (possible during new acf_form).
|
||
|
if ( ! $id ) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Determine CRUD function.
|
||
|
// - Relies on decoded post_id result to identify option or meta types.
|
||
|
// - Uses xxx_metadata(type) instead of xxx_type_meta() to bypass additional logic that could alter the ID.
|
||
|
if ( $type === 'option' ) {
|
||
|
return delete_option( "{$prefix}{$id}_{$name}" );
|
||
|
} else {
|
||
|
return delete_metadata( $type, $id, "{$prefix}{$name}" );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* acf_copy_postmeta
|
||
|
*
|
||
|
* Copies meta from one post to another. Useful for saving and restoring revisions.
|
||
|
*
|
||
|
* @date 25/06/2016
|
||
|
* @since 5.3.8
|
||
|
*
|
||
|
* @param (int|string) $from_post_id The post id to copy from.
|
||
|
* @param (int|string) $to_post_id The post id to paste to.
|
||
|
* @return void
|
||
|
*/
|
||
|
function acf_copy_metadata( $from_post_id = 0, $to_post_id = 0 ) {
|
||
|
|
||
|
// Get all postmeta.
|
||
|
$meta = acf_get_meta( $from_post_id );
|
||
|
|
||
|
// Check meta.
|
||
|
if ( $meta ) {
|
||
|
|
||
|
// Slash data. WP expects all data to be slashed and will unslash it (fixes '\' character issues).
|
||
|
$meta = wp_slash( $meta );
|
||
|
|
||
|
// Loop over meta.
|
||
|
foreach ( $meta as $name => $value ) {
|
||
|
acf_update_metadata( $to_post_id, $name, $value );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* acf_copy_postmeta
|
||
|
*
|
||
|
* Copies meta from one post to another. Useful for saving and restoring revisions.
|
||
|
*
|
||
|
* @date 25/06/2016
|
||
|
* @since 5.3.8
|
||
|
* @deprecated 5.7.11
|
||
|
*
|
||
|
* @param int $from_post_id The post id to copy from.
|
||
|
* @param int $to_post_id The post id to paste to.
|
||
|
* @return void
|
||
|
*/
|
||
|
function acf_copy_postmeta( $from_post_id = 0, $to_post_id = 0 ) {
|
||
|
return acf_copy_metadata( $from_post_id, $to_post_id );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* acf_get_meta_field
|
||
|
*
|
||
|
* Returns a field using the provided $id and $post_id parameters.
|
||
|
* Looks for a reference to help loading the correct field via name.
|
||
|
*
|
||
|
* @date 21/1/19
|
||
|
* @since 5.7.10
|
||
|
*
|
||
|
* @param string $key The meta name (field name).
|
||
|
* @param (int|string) $post_id The post_id where this field's value is saved.
|
||
|
* @return (array|false) The field array.
|
||
|
*/
|
||
|
function acf_get_meta_field( $key = 0, $post_id = 0 ) {
|
||
|
|
||
|
// Try reference.
|
||
|
$field_key = acf_get_reference( $key, $post_id );
|
||
|
|
||
|
if ( $field_key ) {
|
||
|
$field = acf_get_field( $field_key );
|
||
|
if ( $field ) {
|
||
|
$field['name'] = $key;
|
||
|
return $field;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Return false.
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* acf_get_metaref
|
||
|
*
|
||
|
* Retrieves reference metadata from the database.
|
||
|
*
|
||
|
* @date 16/10/2015
|
||
|
* @since 5.2.3
|
||
|
*
|
||
|
* @param (int|string) $post_id The post id.
|
||
|
* @param string type The reference type (fields|groups).
|
||
|
* @param string $name An optional specific name
|
||
|
* @return mixed
|
||
|
*/
|
||
|
function acf_get_metaref( $post_id = 0, $type = 'fields', $name = '' ) {
|
||
|
|
||
|
// Load existing meta.
|
||
|
$meta = acf_get_metadata( $post_id, "_acf_$type" );
|
||
|
|
||
|
// Handle no meta.
|
||
|
if ( ! $meta ) {
|
||
|
return $name ? '' : array();
|
||
|
}
|
||
|
|
||
|
// Return specific reference.
|
||
|
if ( $name ) {
|
||
|
return isset( $meta[ $name ] ) ? $meta[ $name ] : '';
|
||
|
|
||
|
// Or return all references.
|
||
|
} else {
|
||
|
return $meta;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* acf_update_metaref
|
||
|
*
|
||
|
* Updates reference metadata in the database.
|
||
|
*
|
||
|
* @date 16/10/2015
|
||
|
* @since 5.2.3
|
||
|
*
|
||
|
* @param (int|string) $post_id The post id.
|
||
|
* @param string type The reference type (fields|groups).
|
||
|
* @param array $references An array of references.
|
||
|
* @return (int|bool) Meta ID if the key didn't exist, true on successful update, false on failure.
|
||
|
*/
|
||
|
function acf_update_metaref( $post_id = 0, $type = 'fields', $references = array() ) {
|
||
|
|
||
|
// Get current references.
|
||
|
$current = acf_get_metaref( $post_id, $type );
|
||
|
|
||
|
// Merge in new references.
|
||
|
$references = array_merge( $current, $references );
|
||
|
|
||
|
// Simplify groups
|
||
|
if ( $type === 'groups' ) {
|
||
|
$references = array_values( $references );
|
||
|
}
|
||
|
|
||
|
// Remove duplicate references.
|
||
|
$references = array_unique( $references );
|
||
|
|
||
|
// Update metadata.
|
||
|
return acf_update_metadata( $post_id, "_acf_$type", $references );
|
||
|
}
|