# Event RSVP Form With a Guest Limit

> Adds an [wpide_rsvp] shortcode for events: guests reply with their name, email and party size, replies are saved on the event post with a running total, and the form closes when it is full.

- Type: PHP
- Runs: Run everywhere
- Category: [Forms](https://wpide.com/library/category/forms/)
- Tags: rsvp, events, shortcode
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/form-event-rsvp/

## Code

```php
add_action( 'template_redirect', function () {
    if ( empty( $_POST['wpide_rsvp_nonce'] ) || empty( $_POST['wpide_rsvp_post'] ) ) {
        return;
    }

    $post_id = absint( $_POST['wpide_rsvp_post'] );
    $back    = remove_query_arg( 'wpide_rsvp', get_permalink( $post_id ) ? get_permalink( $post_id ) : home_url( '/' ) );
    $done    = function ( $status ) use ( $back ) {
        wp_safe_redirect( add_query_arg( 'wpide_rsvp', $status, $back ) . '#wpide-rsvp' );
        exit;
    };

    if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['wpide_rsvp_nonce'] ) ), 'wpide_rsvp_' . $post_id ) || 'publish' !== get_post_status( $post_id ) ) {
        $done( 'expired' );
    }
    if ( ! empty( $_POST['wpide_rsvp_hp'] ) ) {
        $done( 'thanks' );
    }

    $name   = sanitize_text_field( wp_unslash( isset( $_POST['wpide_rsvp_name'] ) ? $_POST['wpide_rsvp_name'] : '' ) );
    $email  = strtolower( sanitize_email( wp_unslash( isset( $_POST['wpide_rsvp_email'] ) ? $_POST['wpide_rsvp_email'] : '' ) ) );
    $guests = max( 1, min( 10, absint( isset( $_POST['wpide_rsvp_guests'] ) ? $_POST['wpide_rsvp_guests'] : 1 ) ) );
    $limit  = absint( get_post_meta( $post_id, '_wpide_rsvp_limit', true ) );

    if ( '' === $name || ! is_email( $email ) ) {
        $done( 'invalid' );
    }

    $list  = get_post_meta( $post_id, '_wpide_rsvp_list', true );
    $list  = is_array( $list ) ? $list : array();
    $total = array_sum( wp_list_pluck( $list, 'guests' ) );

    if ( isset( $list[ md5( $email ) ] ) ) {
        $done( 'duplicate' );
    }
    if ( $limit && $total + $guests > $limit ) {
        $done( 'full' );
    }

    $list[ md5( $email ) ] = array( 'name' => $name, 'email' => $email, 'guests' => $guests, 'time' => time() );
    update_post_meta( $post_id, '_wpide_rsvp_list', $list );

    wp_mail( $email, 'Your RSVP for ' . wp_strip_all_tags( get_the_title( $post_id ) ), sprintf( "Hi %s,\n\nThanks for your RSVP for %d guest(s). See you there!\n\n%s", $name, $guests, get_permalink( $post_id ) ) );
    $done( 'thanks' );
} );

add_shortcode( 'wpide_rsvp', function ( $atts ) {
    $atts    = shortcode_atts( array( 'limit' => 0 ), $atts, 'wpide_rsvp' );
    $post_id = get_the_ID();

    if ( ! $post_id ) {
        return '';
    }
    if ( (int) get_post_meta( $post_id, '_wpide_rsvp_limit', true ) !== (int) $atts['limit'] && current_user_can( 'edit_post', $post_id ) ) {
        update_post_meta( $post_id, '_wpide_rsvp_limit', absint( $atts['limit'] ) );
    }

    $list  = get_post_meta( $post_id, '_wpide_rsvp_list', true );
    $total = is_array( $list ) ? array_sum( wp_list_pluck( $list, 'guests' ) ) : 0;
    $limit = absint( $atts['limit'] );
    $left  = $limit ? max( 0, $limit - $total ) : null;

    $messages = array(
        'thanks'    => 'Thank you! Your RSVP is confirmed and a confirmation email is on its way.',
        'duplicate' => 'This email address has already replied.',
        'full'      => 'Sorry, there are not enough places left for your party.',
        'invalid'   => 'Please enter your name and a valid email address.',
        'expired'   => 'The form expired. Please try again.',
    );
    $status = isset( $_GET['wpide_rsvp'] ) ? sanitize_key( $_GET['wpide_rsvp'] ) : '';

    $html  = '<div id="wpide-rsvp" class="wpide-form wpide-rsvp">';
    $html .= isset( $messages[ $status ] ) ? '<p class="wpide-form-notice" role="status">' . esc_html( $messages[ $status ] ) . '</p>' : '';

    if ( null !== $left && 0 === $left ) {
        return $html . '<p><strong>This event is fully booked.</strong></p></div>';
    }

    $html .= null !== $left ? '<p>' . esc_html( sprintf( '%d place(s) left.', $left ) ) . '</p>' : '';
    $html .= '<form method="post" action="">';
    $html .= '<p><label for="wpide-rsvp-name">Name</label><br><input id="wpide-rsvp-name" name="wpide_rsvp_name" required autocomplete="name"></p>';
    $html .= '<p><label for="wpide-rsvp-email">Email</label><br><input type="email" id="wpide-rsvp-email" name="wpide_rsvp_email" required autocomplete="email"></p>';
    $html .= '<p><label for="wpide-rsvp-guests">Number of guests (including you)</label><br><input type="number" id="wpide-rsvp-guests" name="wpide_rsvp_guests" min="1" max="10" value="1"></p>';
    $html .= '<p style="position:absolute;left:-9999px;" aria-hidden="true"><input name="wpide_rsvp_hp" tabindex="-1" autocomplete="off"></p>';
    $html .= '<input type="hidden" name="wpide_rsvp_post" value="' . esc_attr( $post_id ) . '">';
    $html .= wp_nonce_field( 'wpide_rsvp_' . $post_id, 'wpide_rsvp_nonce', false, false );
    $html .= '<p><button type="submit">RSVP</button></p></form></div>';

    return $html;
} );

add_action( 'add_meta_boxes', function ( $post_type, $post ) {
    if ( $post && get_post_meta( $post->ID, '_wpide_rsvp_list', true ) ) {
        add_meta_box( 'wpide-rsvp-list', 'RSVPs', function ( $post ) {
            $list = (array) get_post_meta( $post->ID, '_wpide_rsvp_list', true );
            printf( '<p><strong>%d guest(s)</strong> from %d replies</p><ul>', (int) array_sum( wp_list_pluck( $list, 'guests' ) ), count( $list ) );
            foreach ( $list as $row ) {
                printf( '<li>%s &lt;%s&gt; × %d</li>', esc_html( $row['name'] ), esc_html( $row['email'] ), (int) $row['guests'] );
            }
            echo '</ul>';
        }, null, 'side' );
    }
}, 10, 2 );
```

## Notes

Use [wpide_rsvp limit="50"] on the event post or page; each email address can reply once and the guest list appears in a box on that post's edit screen.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Event RSVP Form With a Guest Limit" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
