Hay dos pasos para el método: primero, una función para guardar sus datos de campo de metabox personalizados (enganchado a save_post), y segundo, una función para leer ese nuevo post_meta (que acaba de guardar), validarlo y modificar el resultado de guardar según sea necesario (también enganchado a save_post, pero después del primero). La función del validador, si la validación falla, en realidad cambia el post_status de nuevo a "pendiente", evitando efectivamente la publicación de la publicación.
Como la función save_post se llama mucho, cada función tiene comprobaciones que solo se ejecutan cuando el usuario quiere publicar, y solo para su tipo de publicación personalizada (mycustomtype).
También normalmente agrego algunos mensajes de aviso personalizados para ayudar al usuario a saber por qué su publicación no se publicó, pero es un poco complicado incluirlos aquí ...
No he probado este código exacto, pero es una versión simplificada de lo que he hecho en configuraciones de tipo de publicación personalizada a gran escala.
add_action('save_post', 'save_my_fields', 10, 2);
add_action('save_post', 'completion_validator', 20, 2);
function save_my_fields($pid, $post) {
// don't do on autosave or when new posts are first created
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid;
// abort if not my custom type
if ( $post->post_type != 'mycustomtype' ) return $pid;
// save post_meta with contents of custom field
update_post_meta($pid, 'mymetafield', $_POST['mymetafield']);
}
function completion_validator($pid, $post) {
// don't do on autosave or when new posts are first created
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || $post->post_status == 'auto-draft' ) return $pid;
// abort if not my custom type
if ( $post->post_type != 'mycustomtype' ) return $pid;
// init completion marker (add more as needed)
$meta_missing = false;
// retrieve meta to be validated
$mymeta = get_post_meta( $pid, 'mymetafield', true );
// just checking it's not empty - you could do other tests...
if ( empty( $mymeta ) ) {
$meta_missing = true;
}
// on attempting to publish - check for completion and intervene if necessary
if ( ( isset( $_POST['publish'] ) || isset( $_POST['save'] ) ) && $_POST['post_status'] == 'publish' ) {
// don't allow publishing while any of these are incomplete
if ( $meta_missing ) {
global $wpdb;
$wpdb->update( $wpdb->posts, array( 'post_status' => 'pending' ), array( 'ID' => $pid ) );
// filter the query URL to change the published message
add_filter( 'redirect_post_location', create_function( '$location','return add_query_arg("message", "4", $location);' ) );
}
}
}
Para múltiples campos de metabox, simplemente agregue más marcadores de finalización y recupere más post_meta y realice más pruebas.