最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to check for duplicate record before saving a Custom Post Type

programmeradmin0浏览0评论

I have a custom post type where I need to check for a duplicate record before the record actually gets saved into the database.

The requirement is like this: Before saving a record, I need to check whether another record with the currently provided combination of post_title, county (meta field) and city (meta field) exists already.

I have written the function for searching a similar record:

function mbs_check_duplicate_record() {
    global $post, $wpdb;
    $company = $_REQUEST['post_title'];
    $post_type = $_REQUEST['post_type'];
    $country = $_REQUEST['txtClientsCountryMbs'];
    $city = $_REQUEST['txtClientsCityMbs'];

    $args = array(
        'post_title'      => $company,
        'post_type'       => $post_type,
        'post_status'     => 'publish',
        'posts_per_page'  => 1,

        'meta_query' => array(
            array(
                'key'     => '_mbs_clients_country',
                'value'   => $country,
                'compare' => '='
            ),
            array(
                'key'     => '_mbs_clients_city',
                'value'   => $city,
                'compare' => '='
            )
        ),
    );

    $dup = new WP_Query( $args );

    if( $dup->post_count > 0 ) {
        return false;
    } else {
        return true;
    }
}

I have also deregistered autosave functionality by adding this:

add_action( 'wp_print_scripts', function(){
    wp_deregister_script( 'autosave' );
} );

Then I called the above function inside the function which I am using to hook with save_post like this:

function mbs_save_clients_meta( $post_id ) {

    if(
        ! isset( $_POST['clients_url_nonce'] ) ||
        ! isset( $_POST['clients_city_nonce'] ) ||
        ! isset( $_POST['clients_country_nonce'] ) ||
        ! isset( $_POST['clients_lat_nonce'] ) ||
        ! isset( $_POST['clients_lng_nonce'] ) ) {
        return;
    }

    if( ! current_user_can( 'edit_post', $post_id) ) {
        return;
    }

    if( ! mbs_check_duplicate_record() ) {
        add_filter( 'admin_notices', function(){
            echo '<div id="mbs_duplicate_entry">Client already exists! Please check Name, Country and City.</div>';
        die();
        } );
    } else {
       The save routine starts ...
    }
}

add_action( 'save_post',  'mbs_save_clients_meta' );

But the post always gets save even it finds an existing record.

UPDATE

Actually, when a duplicate record is found, no metadata is saving, but a new post is always getting added with the title. How can I prevent WordPress from doing this, i.e., nothing should be saved if another record with the given combination is already existing in the database?

Also, the admin_notices hook is not displaying my custom message. This is probably because the post is being created?

I have a custom post type where I need to check for a duplicate record before the record actually gets saved into the database.

The requirement is like this: Before saving a record, I need to check whether another record with the currently provided combination of post_title, county (meta field) and city (meta field) exists already.

I have written the function for searching a similar record:

function mbs_check_duplicate_record() {
    global $post, $wpdb;
    $company = $_REQUEST['post_title'];
    $post_type = $_REQUEST['post_type'];
    $country = $_REQUEST['txtClientsCountryMbs'];
    $city = $_REQUEST['txtClientsCityMbs'];

    $args = array(
        'post_title'      => $company,
        'post_type'       => $post_type,
        'post_status'     => 'publish',
        'posts_per_page'  => 1,

        'meta_query' => array(
            array(
                'key'     => '_mbs_clients_country',
                'value'   => $country,
                'compare' => '='
            ),
            array(
                'key'     => '_mbs_clients_city',
                'value'   => $city,
                'compare' => '='
            )
        ),
    );

    $dup = new WP_Query( $args );

    if( $dup->post_count > 0 ) {
        return false;
    } else {
        return true;
    }
}

I have also deregistered autosave functionality by adding this:

add_action( 'wp_print_scripts', function(){
    wp_deregister_script( 'autosave' );
} );

Then I called the above function inside the function which I am using to hook with save_post like this:

function mbs_save_clients_meta( $post_id ) {

    if(
        ! isset( $_POST['clients_url_nonce'] ) ||
        ! isset( $_POST['clients_city_nonce'] ) ||
        ! isset( $_POST['clients_country_nonce'] ) ||
        ! isset( $_POST['clients_lat_nonce'] ) ||
        ! isset( $_POST['clients_lng_nonce'] ) ) {
        return;
    }

    if( ! current_user_can( 'edit_post', $post_id) ) {
        return;
    }

    if( ! mbs_check_duplicate_record() ) {
        add_filter( 'admin_notices', function(){
            echo '<div id="mbs_duplicate_entry">Client already exists! Please check Name, Country and City.</div>';
        die();
        } );
    } else {
       The save routine starts ...
    }
}

add_action( 'save_post',  'mbs_save_clients_meta' );

But the post always gets save even it finds an existing record.

UPDATE

Actually, when a duplicate record is found, no metadata is saving, but a new post is always getting added with the title. How can I prevent WordPress from doing this, i.e., nothing should be saved if another record with the given combination is already existing in the database?

Also, the admin_notices hook is not displaying my custom message. This is probably because the post is being created?

Share Improve this question edited Feb 10, 2020 at 7:32 Subrata Sarkar asked Feb 10, 2020 at 7:25 Subrata SarkarSubrata Sarkar 2395 silver badges16 bronze badges 4
  • Some questions. Are you using Gutenberg or Classic editor? And wouldn't it be enough to allow saving incorrect records, but preventing them from being published? – Vitauts Stočka Commented Feb 10, 2020 at 9:59
  • I am using Classic Editor. Saving needs to be done only if there is no duplicate record found based on a given combination of title, city and country fields. – Subrata Sarkar Commented Feb 10, 2020 at 10:13
  • Sure, I understand your combination requirement. I asked about preventing records from being published because it is easier to do in WordPress. I have some similar use cases where user may create whatever "invalid" records he wants, but those records can't be published, my filter function prevents state change to 'published' if record is invalid. – Vitauts Stočka Commented Feb 10, 2020 at 10:22
  • This should work! But at the same time, I need to show that the record exists as an admin notice. However, is this not possible at all to NOT save such a record at all and display an admin notice? – Subrata Sarkar Commented Feb 10, 2020 at 10:25
Add a comment  | 

1 Answer 1

Reset to default 0

See this answer for solution, see comments there about error messages. That should work with Classic editor.

It could work with Gutenberg too, but it would need additional effort to get correct error messages.

UPDATE:

If using classic editor and preventing publishing of invalid records is enough, you can use this code:

function my_save_post($post_id) {

    if (.. record is not valid ..) {
        // remove Post Published message
        add_filter( 'redirect_post_location', function ( $location ) {
            return preg_replace( '/&message=\d+/', '', $location );
        } );

        // this is important to prevent recursive loop
        remove_action( 'save_post', 'my_save_post' );
        wp_update_post( [ 'ID' => $post_id, 'post_status' => 'draft' ] );
        add_action( 'save_post', 'my_save_post' );

        // admin_notice will not work because of redirect
        // try to change message in redirect_post_location - see above
        // or store transient and here and use it on next request
        // to show error message
        set_transient( 'my_save_errors_' . $post_id, $error_message, 20 );
    }
}

add_action( 'save_post', 'my_save_post' );
发布评论

评论列表(0)

  1. 暂无评论