wp_update_post deletes post meta in CPT

I have a custom post type called 'directory' and it includes a few meta/custom fields. The script below is meant to just change the post status only when run. This isn't on the admin panel where you save the post. This is a stand alone script run by itself.

require('../../../wp-blog-header.php');
global $wpdb;
global $post;

$directories = get_posts( $get_directories );
foreach ($directories as $directory){
 wp_update_post(array('ID' = $directory-ID,'post_status' = 'draft'));
};

The status is updated fine, but the custom meta data is deleted.

I've seen other's with similar problems adding an update on the admin edit page, but this is its own file.

Topic wp-update-post plugin-development Wordpress

Category Web


Based on the source code of wp_publish_post(), you could update the post status without touching meta data and, at the same time, without losing post transition actions (you are missing them in your code) with something like this:

global $wpdb;
// Unkown $get_directories, you have not set it
// in your sample code, I assume it is correct
$directories = get_posts( $get_directories );
foreach( $directories as $directory ){
    // Skip already draft posts
    if( $directory->post_status != 'draft' ) {
        $wpdb->update( $wpdb->posts, array( 'post_status' => 'draft' ), array( 'ID' => $directory->ID ) );
        clean_post_cache( $directory->ID );
        $old_status = $directory->post_status;
        $directory->post_status = 'draft';
        // Perform transition actions
        wp_transition_post_status( 'draft', $old_status, $directory );
    }
}

You could include also other actinos triggered when a post is updated:

do_action( 'edit_post', $directory->ID, $post );
do_action( "save_post_{$directory->post_type}", $directory->ID, $directory, true );
do_action( 'save_post', $directory->ID, $directory, true );
do_action( 'wp_insert_post', $directory->ID, $directory, true );

But, as @Rast said, it is very probably that your problem is with some of these actions hooked by third party code (from another plugin or from the theme). These actions are triggered by wp_update_post() and it is commonly used to update post meta fields, specially save_post action. It is very probably that when these actions are triggered without meta information, like your code does, the third party code deletes the meta fields.


Not sure about the problem with wp_update_post but it is a simple enough SQL query:

global $wpdb;
$query = "UPDATE ".$wpdb->prefix."posts SET post_status='draft' WHERE ID = '".$directory->ID."'";
$wpdb->query($query);

I don't think this should happen by default. From quick look through the code the only case in which update call should affect meta is if you provide meta_input in arguments to apply.

As per comment the case might be that you are trying to interact with third party CPT and its code doesn't handle situation well.

Note that "own file" doesn't matter much (and is pretty bad practice while at it), the WP core will still boot and load all the plugins.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.