Home Forums Front-end Issues Testing for duplicates before saving post using form Reply To: Testing for duplicates before saving post using form

  • Well, i think my problem is quite similar to topic starter’s. I needed to check post_type value and immediately stop post inserting if it was equal to some value. After studying WP Codex i found a nice solution based on wp core behaviour.

    For inserting posts WP uses wp_post_insert() function. And if we check its code, we’ll see some hooks and filters. The most famous are, probably, ‘wp_insert_post’ and ‘save_post’, but the whole thing will look like this:

    1. Getting future post data from form.
    2. Checking if we are updating or creating.
    3. Checking for empty critical post fields (tite, content and excerpt by default).
    – apply_filters( ‘wp_insert_post_empty_content’, $maybe_empty, $postarr ) where $postarr contains all data, passed to wp_insert_post().
    4. Sanitizing and validating all the data.
    5. Checking if there is a valid parent post (page).
    – apply_filters( ‘wp_insert_post_parent’, $post_parent, $post_ID, compact( array_keys( $postarr ) ), $postarr );
    6. Check things before inserting to database.
    – apply_filters( ‘wp_insert_attachment_data’, $data, $postarr ) if it’s attachment.
    – apply_filters( ‘wp_insert_post_data’, $data, $postarr ) if it’s another post type.
    7. If we have post ID then it’s update.
    – do_action( ‘pre_post_update’, $post_ID, $data ). Fires just before updating post in database.
    8. If we don’t have post ID then insert post in database, set taxonomies etc.
    9. Finishing process, do some actions.
    – do_action( ‘edit_attachment’, $post_ID ) if it was an update of attachment.
    – do_action( ‘add_attachment’, $post_ID ) if a new attachment was added.
    – do_action( ‘edit_post’, $post_ID, $post ) if existing post was updated.
    – do_action( ‘post_updated’, $post_ID, $post_after, $post_before) if existing post was updated. Is different from previous action: we get two post arrays, before and after update, so we can compare them.
    – do_action( “save_post_{$post->post_type}”, $post_ID, $post, $update ) if post was saved. Fires for specific post_type and $update shows us was it update (true) or new post insert (false).
    – do_action( ‘save_post’, $post_ID, $post, $update ) if post was saved. The same as previous, but for all post types.
    – do_action( ‘wp_insert_post’, $post_ID, $post, $update ) if post was saved. The same as previous.

    Sorry for long explaining. So, assuming all this, we have one point before inserting post to database, when we can change the things. It is a filter on 6th step. Here is my code piece:

    function filter_handler( $data, $postarr ) {
     if ( $data[ 'post_type' ] == 'technic' ) : // if post_type from form meets my criteria, then do nothing and redirect to homepage (for example)
      wp_safe_redirect( esc_url( home_url() ) ); // using wp function for redirecting
      exit; // don't forget to exit to end redirect
      return; // do nothing more in wp_insert_post()
     else : // if it is any another post_type
      return $data; // then do all as usual and don't forget to return $data to function
    add_filter( 'wp_insert_post_data', 'filter_handler', '99', 2 );