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.