Support

Account

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

Solving

Testing for duplicates before saving post using form

  • I don’t want to “reinvent the wheel” here and I would imagine there is a “best practice” for this already. I would think this would have already been thought of and that possibly even ACF Pro has some methods to make this easy.

    I want to base my test comparing field(s) in the form to posts already saved and if they have a post_status of ‘publish’.

    I have been trying to work this out using WP Queries but is there a more efficient and already coded way?

  • Ultimately what I want to do and can’t seem to circumvent, is to NOT save the post at all if a published post already exists based upon the compare criteria.

  • In trying to sort this out, it seems to boil down to the fact that the post is being saved no matter what. I want to circumvent the save if certain criteria are not met. In this case, that no previous post exists with the same title in a published state.

    In my code sample, I am leaving the testing for that out because the primary issue is that I can’t seem to find a way to terminate the process before the pose gets saved. I am missing some step I think.

    In my plugin file I make a call to:

    add_action( ‘acf/pre_save_post’, ‘my_custom_post_type_function’, 1 );

    function my_custom_post_type_function() {
    // For the test, just terminate and return
    return;
    }

    My Template file to create a new post entry looks like this:

    <?php
    /**
    * Template Name: Post Entry for CPT
    *
    * @package WordPress
    * @subpackage Twenty_Twelve
    * @since Twenty Twelve 1.0
    */
    acf_form_head(); ?>
    <?php get_header(); ?>

    <div id=”primary” class=”content-area”>
    <div id=”content” class=”site-content” role=”main”>
    <?php /* The loop */ ?>
    <?php while ( have_posts() ) : the_post(); ?>
    <?php acf_form( array(
    ‘post_id’ => ‘new_post’,
    ‘new_post’ => array(
    ‘post_type’ => ‘custom-post’,
    ‘post_status’ => ‘publish’,
    ‘category’ => ‘custom-post-category’,
    ‘submit_value’ => ‘Create a new post entry’
    )

    )); ?>
    <?php endwhile; ?>
    </div>
    <!– #content –>
    </div><!– #primary –>

    <?php get_sidebar(); ?>
    <?php get_footer(); ?>

  • Even doing this with no other hooks is saving data:

    // Save the post
    add_action(‘acf/save_post’, ‘my_save_the_post’, 1);
    function my_save_the_post() {

    return;
    }

    Anyone? I’m stumped

  • The reason that the post is still being saved is that acf/save_post is run when the WP save_post action fires and this only happens after the post is already saved.

    You’re going to need to find a way to hook into the WP save before it inserts the new post and do your checking there. I tried some quick searching on how to do this but didn’t find much. Apparently my search foo is not strong tonight.

  • 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
     endif;
    }
    add_filter( 'wp_insert_post_data', 'filter_handler', '99', 2 );
Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.