I’m trying to do some server side validation of post fields (custom and/or non-custom fields). Validation works just fine, but I can’t seem to stop the post from saving if validation fails.
I tried hooks like save_post
, publish_post
, wp_insert_post_data
, etc. All of these hooks are being called but I can’t stop the post from saving unless I use wp_die()
. To be clear, I do not want to change the post status; I just want to return to the post page (unsaved) and show a message when the validation of a field fails.
I think this is pretty basic stuff, but whatever I do the post is being saved.
UPDATE:
OK, so the pre_post_update
hook is an option. However, on a validation failure I need to use wp_redirect
to get back to the edit page without saving. I’m storing the invalidation msgs and showing them on the page, but this way all the $_POST
data is gone… which of course is not acceptable. Is there really no other way to do this?
Here’s my code so far:
add_action('pre_post_update', 'validate_meta', 99, 2);
function validate_meta($post_id){
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id;
if (!isset($_POST['post_type']) ) return $post_id;
if ( !current_user_can( 'edit_posts', $post_id ) ) return $post_id;
$errors = array();
if(trim($_POST['post_title']) == ''){
$errors[] = new WP_Error('cpt_validation_titke', 'Bitte einen Titel eintragen', 'error');
}
if (!empty($errors)) {
add_user_meta(get_current_user_id(), 'admin_notices', $errors, true);
$url = admin_url( 'post.php?post=" . $post_id ) . "&action=edit';
//exit;
wp_redirect( $url );
exit;
}
return $_POST;
}
// Display any errors
add_action( 'admin_notices', 'admin_notice_handler' );
function admin_notice_handler() {
$user_id = get_current_user_id();
$admin_notices = get_user_meta($user_id, 'admin_notices', true);
if(!empty($admin_notices)){
$html="";
if(is_wp_error($admin_notices[0])){
delete_user_meta($user_id, 'admin_notices');
foreach($admin_notices AS $notice){
$msgs = $notice->get_error_messages();
if(!empty($msgs)){
$msg_type = $notice->get_error_data();
if(!empty($notice_type)){
$html .= '<div class="'.$msg_type.'">';
} else {
$html .= '<div class="error">';
$html .= '<p><strong>Validation errors</strong></p>';
}
foreach($msgs as $msg){
$html .= '<p>- '.$msg.'</p>';
}
$html .= '</div>';
}
}
}
echo $html;
}
}