945 lines
23 KiB
PHP
945 lines
23 KiB
PHP
<?php
|
|
/**
|
|
* @package ACF
|
|
* @author WP Engine
|
|
*
|
|
* © 2025 Advanced Custom Fields (ACF®). All rights reserved.
|
|
* "ACF" is a trademark of WP Engine.
|
|
* Licensed under the GNU General Public License v2 or later.
|
|
* https://www.gnu.org/licenses/gpl-2.0.html
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly.
|
|
}
|
|
|
|
if ( ! class_exists( 'ACF_Internal_Post_Type' ) ) {
|
|
abstract class ACF_Internal_Post_Type {
|
|
|
|
/**
|
|
* The ACF internal post type name.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $post_type = '';
|
|
|
|
/**
|
|
* The prefix for the key used in the main post array.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $post_key_prefix = '';
|
|
|
|
/**
|
|
* The cache key for a singular post.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $cache_key = '';
|
|
|
|
/**
|
|
* The cache key for a collection of posts.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $cache_key_plural = '';
|
|
|
|
/**
|
|
* The hook name for a singular post.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $hook_name = '';
|
|
|
|
/**
|
|
* The hook name for a collection of posts.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $hook_name_plural = '';
|
|
|
|
/**
|
|
* The name of the store used for the post type.
|
|
*
|
|
* @var string
|
|
*/
|
|
public $store = '';
|
|
|
|
/**
|
|
* Constructs the class.
|
|
*/
|
|
public function __construct() {
|
|
acf_register_store( $this->store )->prop( 'multisite', true );
|
|
|
|
$internal_post_types_store = acf_get_store( 'internal-post-types' );
|
|
|
|
if ( ! $internal_post_types_store ) {
|
|
$internal_post_types_store = acf_register_store( 'internal-post-types' );
|
|
}
|
|
|
|
$internal_post_types_store->set( $this->post_type, get_class( $this ) );
|
|
|
|
add_action( "acf/validate_{$this->hook_name}", array( $this, 'translate_post' ) );
|
|
|
|
add_filter( 'wp_unique_post_slug', array( $this, 'apply_unique_post_slug' ), 999, 6 );
|
|
add_action( 'wp_untrash_post_status', array( $this, 'untrash_post_status' ), 10, 3 );
|
|
}
|
|
|
|
/**
|
|
* Get an ACF CPT object as an array.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer|WP_Post $id The post ID being queried.
|
|
* @return array|boolean The main ACF array for the post, or false on failure.
|
|
*/
|
|
public function get_post( $id = 0 ) {
|
|
// Allow WP_Post to be passed.
|
|
if ( is_object( $id ) ) {
|
|
$id = $id->ID;
|
|
}
|
|
|
|
// Check store.
|
|
$store = acf_get_store( $this->store );
|
|
if ( $store->has( $id ) ) {
|
|
return $store->get( $id );
|
|
}
|
|
|
|
if ( acf_is_local_internal_post_type( $id, $this->post_type ) ) {
|
|
$post = acf_get_local_internal_post_type( $id, $this->post_type );
|
|
} else {
|
|
$post = $this->get_raw_post( $id );
|
|
}
|
|
|
|
// Bail early if no post.
|
|
if ( ! $post ) {
|
|
return false;
|
|
}
|
|
|
|
$post = $this->validate_post( $post );
|
|
|
|
/**
|
|
* Filters the post array after it has been loaded.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The post array.
|
|
*/
|
|
$post = apply_filters( "acf/load_{$this->hook_name}", $post );
|
|
|
|
// Store field group using aliases to also find via key, ID and name.
|
|
$store->set( $post['key'], $post );
|
|
$store->alias( $post['key'], $post['ID'] );
|
|
|
|
return $post;
|
|
}
|
|
|
|
/**
|
|
* Retrieves raw post data for the given identifier.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer|string $id The field ID, key or name.
|
|
* @return array|false The field group array, or false on failure.
|
|
*/
|
|
public function get_raw_post( $id = 0 ) {
|
|
// Get raw internal post from database.
|
|
$post = $this->get_post_object( $id );
|
|
if ( ! $post ) {
|
|
return false;
|
|
}
|
|
|
|
// Bail early if incorrect post type.
|
|
if ( $post->post_type !== $this->post_type ) {
|
|
return false;
|
|
}
|
|
|
|
// Unserialize post_content.
|
|
$raw_post = (array) acf_maybe_unserialize( $post->post_content );
|
|
|
|
// Update attributes.
|
|
$raw_post['ID'] = $post->ID;
|
|
$raw_post['title'] = $post->post_title;
|
|
$raw_post['key'] = $post->post_name;
|
|
$raw_post['menu_order'] = $post->menu_order;
|
|
$raw_post['active'] = in_array( $post->post_status, array( 'publish', 'auto-draft' ) );
|
|
|
|
return $raw_post;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the WP_Post object for an ACF internal CPT.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer|string $id The post ID, key, or name.
|
|
* @return WP_Post|boolean The post object, or false on failure.
|
|
*/
|
|
public function get_post_object( $id = 0 ) {
|
|
if ( is_numeric( $id ) ) {
|
|
$post_object = get_post( $id );
|
|
|
|
if ( $post_object && $post_object->post_type === $this->post_type ) {
|
|
return $post_object;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( is_string( $id ) ) {
|
|
// Try cache.
|
|
$cache_key = $this->cache_key . $id;
|
|
$post_id = wp_cache_get( $cache_key, 'acf' );
|
|
|
|
if ( $post_id === false ) {
|
|
$query_key = 'acf_' . $this->post_key_prefix . 'key';
|
|
|
|
// Query posts.
|
|
$posts = get_posts(
|
|
array(
|
|
'posts_per_page' => 1,
|
|
'post_type' => $this->post_type,
|
|
'post_status' => array( 'publish', 'acf-disabled', 'trash' ),
|
|
'orderby' => 'menu_order title',
|
|
'order' => 'ASC',
|
|
'suppress_filters' => false,
|
|
'cache_results' => true,
|
|
'update_post_meta_cache' => false,
|
|
'update_post_term_cache' => false,
|
|
$query_key => $id, // Used to check post_name for field group/post type/taxonomy key.
|
|
)
|
|
);
|
|
|
|
// Update $post_id with a non-false value.
|
|
$post_id = $posts ? $posts[0]->ID : 0;
|
|
|
|
// Update cache.
|
|
wp_cache_set( $cache_key, $post_id, 'acf' );
|
|
}
|
|
|
|
// Check $post_id and return the post when possible.
|
|
if ( $post_id ) {
|
|
return get_post( $post_id );
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the given identifier is an ACF post key.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param string $id The identifier.
|
|
* @return boolean
|
|
*/
|
|
public function is_post_key( $id = '' ) {
|
|
// Check if $id is a string starting with $this->post_key.
|
|
if ( is_string( $id ) && substr( $id, 0, strlen( $this->post_key_prefix ) ) === $this->post_key_prefix ) {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Filters whether the $id is an ACF post key.
|
|
*
|
|
* @date 23/1/19
|
|
* @since 5.7.10
|
|
*
|
|
* @param bool $bool The result.
|
|
* @param string $id The identifier.
|
|
*/
|
|
return apply_filters( "acf/is_{$this->hook_name}_key", false, $id, $this->post_type );
|
|
}
|
|
|
|
/**
|
|
* Validates an ACF internal post type.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The main post array.
|
|
* @return array
|
|
*/
|
|
public function validate_post( $post = array() ) {
|
|
// Bail early if already valid.
|
|
if ( is_array( $post ) && ! empty( $post['_valid'] ) ) {
|
|
return $post;
|
|
}
|
|
|
|
$post = wp_parse_args(
|
|
$post,
|
|
$this->get_settings_array()
|
|
);
|
|
|
|
// Convert types.
|
|
$post['ID'] = (int) $post['ID'];
|
|
$post['menu_order'] = (int) $post['menu_order'];
|
|
$post['active'] = (bool) $post['active'];
|
|
|
|
// Post is now valid.
|
|
$post['_valid'] = true;
|
|
|
|
/**
|
|
* Filters the ACF post array to validate settings.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The post array.
|
|
*/
|
|
return apply_filters( "acf/validate_{$this->hook_name}", $post );
|
|
}
|
|
|
|
/**
|
|
* Validates post type values before allowing save from the global $_POST object.
|
|
* Errors are added to the form using acf_add_internal_post_type_validation_error().
|
|
*
|
|
* @since 6.1
|
|
*/
|
|
public function ajax_validate_values() {}
|
|
|
|
/**
|
|
* Ensures the given ACF post is valid.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The main post array.
|
|
* @return array
|
|
*/
|
|
public function get_valid_post( $post = false ) {
|
|
return $this->validate_post( $post );
|
|
}
|
|
|
|
/**
|
|
* Gets the default settings array for an ACF post type.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_settings_array() {
|
|
return array();
|
|
}
|
|
|
|
/**
|
|
* Translates an ACF post.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The field group array.
|
|
* @return array
|
|
*/
|
|
public function translate_post( $post = array() ) {
|
|
// Get settings.
|
|
$l10n = acf_get_setting( 'l10n' );
|
|
$l10n_textdomain = acf_get_setting( 'l10n_textdomain' );
|
|
|
|
// Translate field settings if textdomain is set.
|
|
if ( $l10n && $l10n_textdomain ) {
|
|
$post['title'] = acf_translate( $post['title'] );
|
|
|
|
/**
|
|
* Filters the post array to translate strings.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The post array.
|
|
*/
|
|
$post = apply_filters( "acf/translate_{$this->hook_name}", $post );
|
|
}
|
|
|
|
return $post;
|
|
}
|
|
|
|
/**
|
|
* Returns an array of ACF posts for the given $filter.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $filter An array of args to filter by.
|
|
* @return array
|
|
*/
|
|
public function get_posts( $filter = array() ) {
|
|
$posts = array();
|
|
|
|
// Check database.
|
|
$raw_posts = $this->get_raw_posts();
|
|
if ( $raw_posts ) {
|
|
foreach ( $raw_posts as $raw_post ) {
|
|
$posts[] = $this->get_post( $raw_post['ID'] );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Filters the posts array.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $posts The array of ACF posts.
|
|
*/
|
|
$posts = apply_filters( "acf/load_{$this->hook_name_plural}", $posts, $this->post_type );
|
|
|
|
// Filter results.
|
|
if ( $filter && $posts ) {
|
|
return $this->filter_posts( $posts, $filter );
|
|
}
|
|
|
|
return $posts;
|
|
}
|
|
|
|
/**
|
|
* Returns an array of raw ACF post data.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @return array
|
|
*/
|
|
public function get_raw_posts() {
|
|
// Try cache.
|
|
$cache_key = acf_cache_key( $this->cache_key_plural );
|
|
$post_ids = wp_cache_get( $cache_key, 'acf' ); // TODO: Do we need to change the group at all?
|
|
|
|
if ( $post_ids === false ) {
|
|
|
|
// Query posts.
|
|
$posts = get_posts(
|
|
array(
|
|
'posts_per_page' => -1,
|
|
'post_type' => $this->post_type,
|
|
'orderby' => 'menu_order title',
|
|
'order' => 'ASC',
|
|
'suppress_filters' => false, // Allow WPML to modify the query.
|
|
'cache_results' => true,
|
|
'update_post_meta_cache' => false,
|
|
'update_post_term_cache' => false,
|
|
'post_status' => array( 'publish', 'acf-disabled' ),
|
|
)
|
|
);
|
|
|
|
// Update $post_ids with a non-false value.
|
|
$post_ids = array();
|
|
foreach ( $posts as $post ) {
|
|
$post_ids[] = $post->ID;
|
|
}
|
|
|
|
// Update cache.
|
|
wp_cache_set( $cache_key, $post_ids, 'acf' );
|
|
}
|
|
|
|
// Loop over ids and populate array of ACF posts.
|
|
$return = array();
|
|
foreach ( $post_ids as $post_id ) {
|
|
$raw_post = $this->get_raw_post( $post_id );
|
|
if ( $raw_post ) {
|
|
$return[] = $raw_post;
|
|
}
|
|
}
|
|
|
|
return $return;
|
|
}
|
|
|
|
/**
|
|
* Filter the posts returned by $this->get_posts().
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $posts An array of posts to filter.
|
|
* @param array $args An array of args to filter by.
|
|
* @return array
|
|
*/
|
|
public function filter_posts( $posts, $args = array() ) {
|
|
if ( ! empty( $args['active'] ) ) {
|
|
$posts = array_filter(
|
|
$posts,
|
|
function ( $post ) {
|
|
return $post['active'];
|
|
}
|
|
);
|
|
}
|
|
|
|
return $posts;
|
|
}
|
|
|
|
/**
|
|
* Updates an ACF post.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The ACF post to update.
|
|
* @return array
|
|
*/
|
|
public function update_post( $post ) {
|
|
// Validate internal post type.
|
|
$post = $this->validate_post( $post );
|
|
|
|
// May have been posted. Remove slashes.
|
|
$post = wp_unslash( $post );
|
|
|
|
// Parse types (converts string '0' to int 0).
|
|
$post = acf_parse_types( $post );
|
|
|
|
/**
|
|
* Fires before updating an ACF post in the database.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The main ACF post array.
|
|
*/
|
|
$post = apply_filters( "acf/pre_update_{$this->hook_name}", $post );
|
|
|
|
// Make a backup of internal post type data and remove some args.
|
|
$_post = $post;
|
|
acf_extract_vars( $_post, array( 'ID', 'key', 'title', 'menu_order', 'fields', 'active', '_valid', '_parent' ) );
|
|
|
|
// Create array of data to save.
|
|
$save = array(
|
|
'ID' => $post['ID'],
|
|
'post_status' => $post['active'] ? 'publish' : 'acf-disabled',
|
|
'post_type' => $this->post_type,
|
|
'post_title' => $post['title'],
|
|
'post_name' => $post['key'],
|
|
'post_excerpt' => sanitize_title( $post['title'] ),
|
|
'post_content' => maybe_serialize( $_post ),
|
|
'menu_order' => $post['menu_order'],
|
|
'comment_status' => 'closed',
|
|
'ping_status' => 'closed',
|
|
'post_parent' => ! empty( $post['_parent'] ) ? (int) $post['_parent'] : 0,
|
|
);
|
|
|
|
// Unhook wp_targeted_link_rel() filter from WP 5.1 corrupting serialized data.
|
|
remove_filter( 'content_save_pre', 'wp_targeted_link_rel' );
|
|
|
|
// Slash data.
|
|
// WP expects all data to be slashed and will unslash it (fixes '\' character issues).
|
|
$save = wp_slash( $save );
|
|
|
|
// Update or Insert.
|
|
if ( $post['ID'] ) {
|
|
wp_update_post( $save );
|
|
} else {
|
|
$post['ID'] = wp_insert_post( $save );
|
|
}
|
|
|
|
$this->flush_post_cache( $post );
|
|
|
|
/**
|
|
* Fires immediately after an ACF post has been updated.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The main ACF post array.
|
|
*/
|
|
do_action( "acf/update_{$this->hook_name}", $post );
|
|
|
|
return $post;
|
|
}
|
|
|
|
/**
|
|
* Allows full control over ACF post slugs.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param string $slug The post slug.
|
|
* @param integer $post_ID Post ID.
|
|
* @param string $post_status The post status.
|
|
* @param string $post_type Post type.
|
|
* @param integer $post_parent Post parent ID.
|
|
* @param string $original_slug The original post slug.
|
|
* @return string
|
|
*/
|
|
public function apply_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
|
|
// Check post type and reset to original value.
|
|
if ( $post_type === $this->post_type ) {
|
|
return $original_slug;
|
|
}
|
|
|
|
return $slug;
|
|
}
|
|
|
|
/**
|
|
* Deletes all caches for this ACF post.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The ACF post array.
|
|
* @return void
|
|
*/
|
|
public function flush_post_cache( $post ) {
|
|
// Delete stored data.
|
|
acf_get_store( $this->store )->remove( $post['key'] );
|
|
|
|
// Flush cached post_id for this field group's key.
|
|
wp_cache_delete( acf_cache_key( $this->cache_key . $post['key'] ), 'acf' );
|
|
|
|
// Flush cached array of post_ids for collection of field groups.
|
|
wp_cache_delete( acf_cache_key( $this->cache_key_plural ), 'acf' );
|
|
}
|
|
|
|
/**
|
|
* Deletes an ACF post.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer|string $id The ID of the ACF post to delete.
|
|
* @return boolean
|
|
*/
|
|
public function delete_post( $id = 0 ) {
|
|
// Disable filters to ensure ACF loads data from DB.
|
|
acf_disable_filters();
|
|
|
|
// Get the post.
|
|
$post = $this->get_post( $id );
|
|
|
|
// Bail early if post was not found.
|
|
if ( ! $post || ! $post['ID'] ) {
|
|
return false;
|
|
}
|
|
|
|
// Delete post and flush cache.
|
|
wp_delete_post( $post['ID'], true );
|
|
$this->flush_post_cache( $post );
|
|
|
|
/**
|
|
* Fires immediately after an ACF post has been deleted.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The ACF post array.
|
|
*/
|
|
do_action( "acf/delete_{$this->hook_name}", $post );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Trashes an ACF post.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer|string $id The ID of the ACF post to trash.
|
|
* @return boolean
|
|
*/
|
|
public function trash_post( $id = 0 ) {
|
|
// Disable filters to ensure ACF loads data from DB.
|
|
acf_disable_filters();
|
|
|
|
$post = $this->get_post( $id );
|
|
if ( ! $post || ! $post['ID'] ) {
|
|
return false;
|
|
}
|
|
|
|
wp_trash_post( $post['ID'] );
|
|
$this->flush_post_cache( $post );
|
|
|
|
/**
|
|
* Fires immediately after a field_group has been trashed.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The ACF post array.
|
|
*/
|
|
do_action( "acf/trash_{$this->hook_name}", $post );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Restores an ACF post from the trash.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer|string $id The ID of the ACF post to untrash.
|
|
* @return boolean
|
|
*/
|
|
public function untrash_post( $id = 0 ) {
|
|
// Disable filters to ensure ACF loads data from DB.
|
|
acf_disable_filters();
|
|
|
|
$post = $this->get_post( $id );
|
|
if ( ! $post || ! $post['ID'] ) {
|
|
return false;
|
|
}
|
|
|
|
wp_untrash_post( $post['ID'] );
|
|
$this->flush_post_cache( $post );
|
|
|
|
/**
|
|
* Fires immediately after an ACF post has been untrashed.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The ACF post array.
|
|
*/
|
|
do_action( "acf/untrash_{$this->hook_name}", $post );
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns the previous post_status instead of "draft" for the ACF internal post types.
|
|
* Prior to WordPress 5.6.0, this filter was not needed as restored posts were always assigned their original status.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param string $new_status The new status of the post being restored.
|
|
* @param integer $post_id The ID of the post being restored.
|
|
* @param string $previous_status The status of the post at the point where it was trashed.
|
|
* @return string
|
|
*/
|
|
public function untrash_post_status( $new_status, $post_id, $previous_status ) {
|
|
return ( get_post_type( $post_id ) === $this->post_type ) ? $previous_status : $new_status;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the given params match an ACF post.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The post array to check.
|
|
* @return boolean
|
|
*/
|
|
public function is_post( $post = false ) {
|
|
return (
|
|
is_array( $post )
|
|
&& isset( $post['key'] )
|
|
&& isset( $post['title'] )
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Duplicates an ACF post.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer|string $id The ID of the post to duplicate.
|
|
* @param integer $new_post_id Optional post ID to override.
|
|
* @return array The new ACF post array.
|
|
*/
|
|
public function duplicate_post( $id = 0, $new_post_id = 0 ) {
|
|
// Disable filters to ensure ACF loads data from DB.
|
|
acf_disable_filters();
|
|
|
|
$post = $this->get_post( $id );
|
|
if ( ! $post || ! $post['ID'] ) {
|
|
return false;
|
|
}
|
|
|
|
// Update attributes.
|
|
$post['ID'] = $new_post_id;
|
|
$post['key'] = uniqid( 'group_' );
|
|
|
|
// Add (copy) to title when appropriate.
|
|
if ( ! $new_post_id ) {
|
|
$post['title'] .= ' (' . __( 'copy', 'acf' ) . ')';
|
|
}
|
|
|
|
// When importing a new field group, insert a temporary post and set the field group's ID.
|
|
// This allows fields to be updated before the field group (field group ID is needed for field parent setting).
|
|
if ( ! $post['ID'] ) {
|
|
$post['ID'] = wp_insert_post(
|
|
array(
|
|
'post_title' => $post['key'],
|
|
'post_type' => $this->post_type,
|
|
)
|
|
);
|
|
}
|
|
|
|
$post = $this->update_post( $post );
|
|
|
|
/**
|
|
* Fires immediately after an ACF post has been duplicated.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The ACF post array.
|
|
*/
|
|
do_action( "acf/duplicate_{$this->hook_name}", $post );
|
|
|
|
return $post;
|
|
}
|
|
|
|
/**
|
|
* Activates or deactivates an ACF post.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer|string $id The ID of the ACF post to activate/deactivate.
|
|
* @param boolean $activate True if the post should be activated.
|
|
* @return boolean
|
|
*/
|
|
public function update_post_active_status( $id, $activate = true ) {
|
|
// Disable filters to ensure ACF loads data from DB.
|
|
acf_disable_filters();
|
|
|
|
$post = $this->get_post( $id );
|
|
if ( ! $post || ! $post['ID'] ) {
|
|
return false;
|
|
}
|
|
|
|
$post['active'] = (bool) $activate;
|
|
$updated_post = $this->update_post( $post );
|
|
|
|
/**
|
|
* Fires immediately after an ACF post has been made active/inactive.
|
|
*
|
|
* @since 6.0.0
|
|
*
|
|
* @param array $updated_post The updated ACF post array.
|
|
*/
|
|
do_action( "acf/update_{$this->hook_name}_active_status", $updated_post );
|
|
|
|
if ( ! isset( $updated_post['active'] ) || $activate !== $updated_post['active'] ) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Checks if the current user can edit ACF posts and returns the edit url.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param integer $post_id The ACF post ID.
|
|
* @return string
|
|
*/
|
|
public function get_post_edit_link( $post_id ) {
|
|
if ( $post_id && acf_current_user_can_admin() ) {
|
|
return admin_url( 'post.php?post=' . $post_id . '&action=edit' );
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Returns a modified ACF post array ready for export.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The ACF post array.
|
|
* @return array
|
|
*/
|
|
public function prepare_post_for_export( $post = array() ) {
|
|
// Remove args.
|
|
acf_extract_vars( $post, array( 'ID', 'local', '_valid' ) );
|
|
|
|
/**
|
|
* Filters the ACF post array before being returned to the export tool.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The ACF post array.
|
|
*/
|
|
return apply_filters( "acf/prepare_{$this->hook_name}_for_export", $post );
|
|
}
|
|
|
|
/**
|
|
* Returns a string containing PHP code that can be used to create the post in ACF.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The post being exported.
|
|
* @return string
|
|
*/
|
|
public function export_post_as_php( $post = array() ) {
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* Formats code used for PHP exports.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param string $code The code being formatted.
|
|
* @return string
|
|
*/
|
|
public function format_code_for_export( $code = '' ) {
|
|
if ( ! is_string( $code ) ) {
|
|
return '';
|
|
}
|
|
|
|
$str_replace = array(
|
|
' ' => "\t",
|
|
"'!!__(!!\'" => "__( '",
|
|
"!!\', !!\'" => "', '",
|
|
"!!\')!!'" => "' )",
|
|
'array (' => 'array(',
|
|
);
|
|
|
|
$preg_replace = array(
|
|
'/([\t\r\n]+?)array/' => 'array',
|
|
'/[0-9]+ => array/' => 'array',
|
|
);
|
|
|
|
$code = str_replace( array_keys( $str_replace ), array_values( $str_replace ), $code );
|
|
$code = preg_replace( array_keys( $preg_replace ), array_values( $preg_replace ), $code );
|
|
|
|
return $code;
|
|
}
|
|
|
|
/**
|
|
* Prepares an ACF post for import.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The ACF post array.
|
|
* @return array
|
|
*/
|
|
public function prepare_post_for_import( $post ) {
|
|
/**
|
|
* Filters the ACF post array before being returned to the import tool.
|
|
*
|
|
* @date 21/11/19
|
|
* @since 5.8.8
|
|
*
|
|
* @param array $post The ACF post array.
|
|
*/
|
|
return apply_filters( "acf/prepare_{$this->hook_name}_for_import", $post );
|
|
}
|
|
|
|
/**
|
|
* Imports an ACF post into the database.
|
|
*
|
|
* @since 6.1
|
|
*
|
|
* @param array $post The ACF post array.
|
|
* @return array
|
|
*/
|
|
public function import_post( $post ) {
|
|
// Disable filters to ensure data is not modified by local, clone, etc.
|
|
$filters = acf_disable_filters();
|
|
|
|
// Validate the post (ensures all settings exist).
|
|
$post = $this->get_valid_post( $post );
|
|
|
|
// Prepare post for import (modifies settings).
|
|
$post = $this->prepare_post_for_import( $post );
|
|
|
|
// Save field group.
|
|
$post = $this->update_post( $post );
|
|
|
|
// Enable filters again.
|
|
acf_enable_filters( $filters );
|
|
|
|
/**
|
|
* Fires immediately after an ACF post has been imported.
|
|
*
|
|
* @date 12/02/2014
|
|
* @since 5.0.0
|
|
*
|
|
* @param array $post The ACF post array.
|
|
*/
|
|
do_action( "acf/import_{$this->hook_name}", $post );
|
|
|
|
return $post;
|
|
}
|
|
}
|
|
|
|
}
|