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

How to prevent multiple post with same meta value being created simultaneously in Wordpress (with ajax)

programmeradmin0浏览0评论

I'm trying to make my own appointment system for WordPress. For this, I created a post type called "appointments". When users select a service from the service list, the available dates and times are listed. When the available date and time are selected and the appointment is created, a meta key named "appointment_datetime" is added for this appointment. Here is where the problem started.

Two different users should not be able to make an appointment for the same service at the same time. Therefore, when a user tries to create an appointment, the following method is used to check whether the date and time he chose are available.

$already_reserved = new WP_Query(array(
    'post_type' => 'appointments',
    'fields' => 'ids',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => 'datetime',
            'value' => $date_time, // timestamps
            'type' => 'numeric',
            'compare' => '='
        )
    ),
    'tax_query' => array(
        array(
            'taxonomy' => 'services',
            'field' => 'id',
            'terms' => $service_id,
        )
    )
));
if ( !empty($already_reserved->posts) ) {
    $response = 'Sorry, this date is full.';
} else {
    // create new appointment post
    // ...
}

And here is the ajax code I used:

var $response = jQuery('#response');
$('#createnew').click(function () {
    var service = document.getElementById('service').value;
    var datetime = document.getElementById('datetime').value;
    $response.html("<div class='loading'>Waiting...</div>");

    $.ajax({
        type: 'POST',
        url: myajax.ajaxurl,
        data: {
            action: 'new_appoitment',
            service: service,
            datetime: datetime,
            // ... another customer details
        },
        success: function(data, textStatus, XMLHttpRequest) {
            $response.html('');
            $response.append(data);
        }
    });
});

After all; When two different users click the button at the same time, they can create an appointment for the same date and time. Is there any way I can prevent this?

I'm trying to make my own appointment system for WordPress. For this, I created a post type called "appointments". When users select a service from the service list, the available dates and times are listed. When the available date and time are selected and the appointment is created, a meta key named "appointment_datetime" is added for this appointment. Here is where the problem started.

Two different users should not be able to make an appointment for the same service at the same time. Therefore, when a user tries to create an appointment, the following method is used to check whether the date and time he chose are available.

$already_reserved = new WP_Query(array(
    'post_type' => 'appointments',
    'fields' => 'ids',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => 'datetime',
            'value' => $date_time, // timestamps
            'type' => 'numeric',
            'compare' => '='
        )
    ),
    'tax_query' => array(
        array(
            'taxonomy' => 'services',
            'field' => 'id',
            'terms' => $service_id,
        )
    )
));
if ( !empty($already_reserved->posts) ) {
    $response = 'Sorry, this date is full.';
} else {
    // create new appointment post
    // ...
}

And here is the ajax code I used:

var $response = jQuery('#response');
$('#createnew').click(function () {
    var service = document.getElementById('service').value;
    var datetime = document.getElementById('datetime').value;
    $response.html("<div class='loading'>Waiting...</div>");

    $.ajax({
        type: 'POST',
        url: myajax.ajaxurl,
        data: {
            action: 'new_appoitment',
            service: service,
            datetime: datetime,
            // ... another customer details
        },
        success: function(data, textStatus, XMLHttpRequest) {
            $response.html('');
            $response.append(data);
        }
    });
});

After all; When two different users click the button at the same time, they can create an appointment for the same date and time. Is there any way I can prevent this?

Share Improve this question asked Nov 28, 2020 at 17:34 FarukFaruk 2510 bronze badges 6
  • The likelihood that two users will submit/click at exactly the same time is really small. We're talking milliseconds... What you could do if you wanted to be absolutely certain is create a 'hold' record, a temporary record in the DB that sets a 'date/time' as being held and check that before you allow a user to submit the appointment request. But then, what if two people are selecting the date/time at the exact same time? I think what you really need to do is just run a validation that the date/time is not taken before adding to the database. – Tony Djukic Commented Nov 29, 2020 at 3:47
  • Yes, it is really unlikely. However, sometimes I may encounter such a situation during really busy periods. It's actually more than milliseconds. It gives the same result in about 5-6 seconds. @TonyDjukic – Faruk Commented Nov 29, 2020 at 19:48
  • I can see a user getting frustrated booking their time slot and then learning it’s no longer available. For user experience I’d consider placing a hold on a date/time, so at least that way you don’t have two users booking a time slot. You could do it using transients. – Tony Djukic Commented Nov 29, 2020 at 22:09
  • Well, can you explain this with a short example? @TonyDjukic – Faruk Commented Nov 29, 2020 at 22:27
  • Not really; there’s far too many things I don’t know about your system/set-up to even begin addressing this. Are the time slots pre-configured, are they postmeta, are the custom-posts, are they taxonomies, do they even use the WordPress data structure? Is this a third party plugin being used? Is it all entirely custom? – Tony Djukic Commented Nov 30, 2020 at 1:32
 |  Show 1 more comment

1 Answer 1

Reset to default 0

first of all at the end of using a new WP_Query it's good pratice to always use wp_reset_postdata(); to be sure nothing had compromise your database.

$already_reserved = new WP_Query(array(
    'post_type' => 'appointments',
    'fields' => 'ids',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'key' => 'datetime',
            'value' => $date_time, // timestamps
            'type' => 'numeric',
            'compare' => '='
        )
    ),
    'tax_query' => array(
        array(
            'taxonomy' => 'services',
            'field' => 'id',
            'terms' => $service_id,
        )
    )
  wp_reset_postdata();
));

and to answer your question, why don't use another if when the button is pressed, right before the appointment is set on the database. like so

if ( !empty($already_reserved->posts) ) {
    $response = 'Sorry, this date is full.';
} else {
    // create new appointment post
    // ...
    // the user has everything and click the button
    if ( !empty($already_reserved->posts) ) {
        $response = 'Sorry, this date is no longer available.'; 
    } else {
    // the appointment is set on the database
    }
}

this is supposing that first there is a validation of the date and only after that the user / users press the button to confirm. if the button has a specific function try to edit that function to make this validation before set the appointment on the database.

发布评论

评论列表(0)

  1. 暂无评论