wp_back/wp-content/plugins/advanced-custom-fields/includes/acf-meta-functions.php
2024-05-20 15:37:46 +03:00

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 );
}