The code uses the save_post
hook to save the results of the form, however, at no point did it check which post it was saving.
This means your save function runs for that post, but it also runs for drafts, autosaves, etc
Then, on top of that there are checks like this:
if( isset( $_POST['cpt_cpts'] ) ) {
update_post_meta( $post_id, 'cpt_cpts', $_POST['cpt_cpts'] );
} else {
delete_post_meta( $post_id, 'cpt_cpts' );
}
If cpt_cpts
is undefined it will delete the post meta, causing the problem you are experiencing. This is incorrect, cpt_cpts
being undefined doesn’t mean that cpt_cpts
needs to be deleted. This may not be a submission of the post form but a minor update from an unrelated piece of code such as a plugin.
A quick way of reproducing this should be using the quick edit feature, this would update the post even though your select input is not on the page or a part of the update process.
Instead the save handler also needs to check for this, e.g. by checking if the nonce exists, or that another form input exists, as well as the post type of the post being saved, and other details.