Limit bookings to one ticket

In some situations you’ll only want to limit bookings to one ticket and/or prevent bookees from making additional bookings for events for which they have already placed bookings for. In this article I’ll walk you through how you can achieve that.

First let’s look at the function we’ll be making use of: eo_user_has_bookings(). You can see its codex page here. This function takes up to 4 arguments

  • User ID – The ID of the user you want to check. (Typically you’ll want to pass the ID of the user currently logged in).
  • Event ID – If checking bookings for a particular event, this is the event’s (post) ID
  • Occurrence ID – If checking bookings for a particular occurrence, this is the occurrence’s ID. You must also pass the event ID. If you are booking ‘by series’, simply give this the value 0.
  • Status – Booking status(es) that we consider. We may want to check if they have any confirmed bookings, or if they have made any bookings – pending or confirmed. Defaults to ‘any’. You can also pass an array of booking statuses.

Hide the booking form if a user has already made a booking

The following code checks if we are on an event’s page, and then checks if the current user has made a booking (pending or confirmed) for that event. Note: If you are booking events ‘by date’, and do not mind if a bookee makes multiple bookings for different dates of the same event, you should ignore this step.

/**
 * Hides the booking form if user has already made a booking for this event
 *
 * If you want them to be able to book several dates for the same event - remove this 
 */
add_action( 'wp_head', 'myprefix_maybe_remove_booking_table' );
function myprefix_maybe_remove_booking_table(){

    if( is_singular( 'event' ) && eo_user_has_bookings( get_current_user_id(),  get_the_ID(), null, eo_get_reserved_booking_statuses() ) ){
        remove_filter( 'the_content', 'eventorganiser_display_booking_table', 999 );
    }
}

Limiting number of tickets in a booking

The above was ‘purely aesthetic’ in the sense that it would technically be possible (with a lot of very difficult guesswork) for a user to place additional bookings. Though very unlikely its important to conduct checks server side to prevent this – or accidental duplicate submissions.

In any case, though the above removes the booking form if the user has made a prior booking, we still need to limit bookings to one ticket.

This next snippet runs when a booking has been submitted and is being validated. It performs the same check as the first section as well as ensuring the booking contains only one ticket. If it fails these checks, it adds an error which cancels the booking process and returns the user to the booking form with the appropriate error message.

/**
 * Limits bookees to one booking per event
 * Limits bookings to one ticket
 *
 * @param array Data posted form the booking form
 * @param object Booking form object
 * @param WP_Error Error object to add any errors to
 */
function myprefix_limit_tickets_in_booking( $input, $form, $errors ){

    $input = $input + array( 'event_id' => 0, 'occurrence_id' => 0, 'gateway' => false, 'tickets'=>array() );
    $tickets = $input['tickets'];
    $post_id = $input['event_id'];
    $occurrence_id = $input['occurrence_id'];

    /* $tickets is an array ( ticket type ID => quantity purchased ). 
       Remove ticket types that have not been selected (0 quantity) */
    $tickets = array_filter( $tickets );

    /* Throw error if user has previously made a booking for this event */
    if( eo_user_has_bookings( get_current_user_id(),  $post_id, $occurrence_id, eo_get_reserved_booking_statuses() ) ){
        //This error will prevent the booking from being processed, and display the given error message
        $errors->add( 'previous_booking', 'You have already made a booking for this event.' );
    }

    /* Count how many tickets are in this booking */
    $total_qty =0;
    if ( $tickets ) {
        $total_qty = array_sum( $tickets );
    }

    /* Throw error if booking contains multiple tickets */
    if( $total_qty > 1 ){
        $errors->add( 'too_many_tickets', 'You can only purchase one ticket.' );
    }

    return $input;
}
add_action( 'eventorganiser_validate_booking_submission', 'myprefix_limit_tickets_in_booking', 20, 3 );

And that’s how to prevent a user from purchasing more than one ticket, or placing more than one booking. Of course, to improve user experience it would be better to prevent form submission at all if more than one ticket is selected. Event Organiser Pro in fact provides ‘javascript hooks’, similar to the familiar WordPress actions and filters that allow you to do this. I’ll be covering that another tutorial