WordPress Custom Meta Boxes Validation

Is there any way to validate custom meta box fields without using javascript. If it doesn’t validate I want to stop the post from being saved to the database.

Related posts

Leave a Reply

3 comments

  1. Since the ‘save_post’ action is run AFTER publishing and updating, there’s really no way of validating custom keys without a hackish alternative.

    However, I’m thinking you can mimic the functionality you want by employing ‘save_post’ in the way Viral suggested, but rather than interrupt or cancel the saving process upon a validation error, you can just delete the post altogether:

    add_action('save_post', 'validate_meta');
    function validate_meta($post_id)
    {
        if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
          return $post_id;
        /*USE THIS ONLY IF YOU ARE UTILIZING NONCE FIELDS IN A CUSTOM META BOX
        if ( !wp_verify_nonce( $_POST['metabox_nonce'], basename(__FILE__) ) )
          return $post_id;*/
        /*Use plugin_basename(__FILE__) if this is an actual plugin, rather than
        a part of your theme*/
    
        if ( 'page' == $_POST['post_type'] ) 
        {
            if ( !current_user_can( 'edit_page', $post_id ) )
                return $post_id;
        }
        else
        {
            if ( !current_user_can( 'edit_post', $post_id ) )
                return $post_id;
        }
    
        /*VALIDATE YOUR METADATA HERE HOWEVER YOU LIKE
        if(is_valid($_POST['metadata']))
            $validated = true;
        else
            $validated = false;
        */
    
        if(!$validated)
            wp_delete_post($post_id, true);
        else
            return $post_id;
    }
    

    The only thing to watch out for with this approach is that it will run upon both Publishing and Updating as well. You may want to consider adding a check to ensure that the post is deleted only for newly published posts, and updated posts are rolled back to a previous version and the invalid revision is deleted.

  2. The wp_insert_post_data filter is what you are looking for. Something like this should do the trick:

    add_filter( 'wp_insert_post_data', 'my_validation_function' );
    
    function my_validation_function( $data ) {
        // Don't want to do this on autosave
        if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
            return $data;
        if ( $data['some_key'] != 'some_value' ||
             $_POST['some_meta_key'] != 'some_meta_value' ) {
            $data['post_status'] = 'draft'; // or whatever status to revert to
            add_filter( 'redirect_post_location', 'remove_message'); // remove the publish success message
        }
        return $data;
    }
    
    function remove_message( $location ) {
        return remove_query_arg( 'message', $location);
    }
    
  3. Straight from the WP Codex @ http://codex.wordpress.org/Function_Reference/add_meta_box, you call the save_post hook and specify the function that will be run to validate/save your data:

    /* Do something with the data entered */
    add_action('save_post', 'myplugin_save_postdata');
    

    Then you define that function, which will automatically be passed the post id. Additionally, you can access the $_POST array to get the values in your metaboxes:

    /* When the post is saved, saves our custom data */
    function myplugin_save_postdata( $post_id ) {
      // verify if this is an auto save routine. 
      // If it is our form has not been submitted, so we dont want to do anything
      if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
          return $post_id;
    
      // verify this came from the our screen and with proper authorization,
      // because save_post can be triggered at other times
    
      if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) ) )
          return $post_id;
    
    
      // Check permissions
      if ( 'page' == $_POST['post_type'] ) 
      {
        if ( !current_user_can( 'edit_page', $post_id ) )
            return $post_id;
      }
      else
      {
        if ( !current_user_can( 'edit_post', $post_id ) )
            return $post_id;
      }
    
      // OK, we're authenticated: we need to find and save the data
    
      $mydata = $_POST['myplugin_new_field'];
    
      // Do something with $mydata 
      // probably using add_post_meta(), update_post_meta(), or 
      // a custom table (see Further Reading section below)
    
       return $mydata;
    }
    

    All of your routines to valid data will be done within this function. In the end, you will likely save the data using something like:
    update_post_meta('meta_key', 'meta_value');