<?php
/**
 * Main conglomeration of front-end functions.
 *
 * @package rsvp_pro_plugin
 * @since 1.0.0
 */

$rsvp_form_action = '';
$placeholder_text = '';
$rsvp_id          = 0;
// Variable to let us know if this plugin has already been ran on the page and if so we can exit.
$rsvp_has_been_ran = false;

$rsvp_pro_saved_form_vars = array();

$rsvp_pro_saved_form_vars['mainRsvp']  = '';
$rsvp_pro_saved_form_vars['rsvp_note'] = '';
$rsvp_first_name                       = '';
$rsvp_last_name                        = '';
$rsvp_passcode                         = '';
$rsvp_hide_edit_form                   = false;
$rsvp_hide_new_form                    = false;
$rsvp_inside_ajax_request              = false;
$rsvp_text                             = '';
$has_sub_events                        = false;
$attendee_count                        = array();

/**
 * Description: Handles the outputting the rsvp form on the front-end
 *
 * @param string $initial_text The initial text on the page.
 * @param string $rsvp_text The RSVP form related text.
 */
function rsvp_pro_handle_output( $initial_text, $rsvp_text ) {
	global $placeholder_text, $rsvp_id;

	$rsvp_text = '<div id="rsvp_pro_container_' . $rsvp_id . '" class="rsvp_pro_container"><a name="rsvpArea" id="rsvpArea"></a>' . $rsvp_text . '</div>';
	remove_filter( 'the_content', 'wpautop' );

	return str_replace( $placeholder_text, $rsvp_text, $initial_text );
}

/**
 * Looks for the placeholder text instead of using a shortcode.
 *
 * @param  string $text The text of the page.
 *
 * @return bool       True if the placeholder is found and false otherwise.
 */
function rsvp_pro_placeholder_found( $text ) {
	global $placeholder_text;
	global $wpdb;
	global $rsvp_id;
	if ( false !== strpos( $text, '[rsvp-pro-pluginhere-' ) ) {

		// parse it out and try and get the number.
		$start_position   = strpos( $text, '[rsvp-pro-pluginhere-' );
		$end_position     = strpos( $text, ']', $start_position );
		$placeholder_text = substr( $text, $start_position, ( $end_position - $start_position ) + 1 );

		// Grab the ID.
		$tmp_id = str_replace( '[rsvp-pro-pluginhere-', '', $placeholder_text );
		$tmp_id = str_replace( ']', '', $tmp_id );

		// Check to see if the id is valid.
		$id = $wpdb->get_var( $wpdb->prepare( 'SELECT id FROM ' . PRO_EVENT_TABLE . ' WHERE id = %d', $tmp_id ) );
		if ( isset( $id ) && ( $id > 0 ) ) {
			$rsvp_id = $id;

			return true;
		}
	}

	return false;
}

/**
 * Main frontend handler for the RSVP plguin
 *
 * @param  string $text The text that needs to be replaced.
 * @param  bool   $hide_edit_form Hides the edit form no matter what.
 * @param  bool   $hide_new_form Hides the new form no matter what.
 *
 * @return string       The text with the form.
 */
function rsvp_pro_frontend_handler( $text, $hide_edit_form = false, $hide_new_form = false ) {
	global $wpdb;
	global $rsvp_id;
	global $rsvp_has_been_ran;
	global $rsvp_pro_saved_form_vars;
	global $rsvp_hide_edit_form;
	global $rsvp_hide_new_form;
	global $rsvp_text;
	global $rsvp_form_action;
	$rsvp_hide_new_form  = $hide_new_form;
	$rsvp_hide_edit_form = $hide_edit_form;

	if ( ! rsvp_pro_placeholder_found( $text ) ) {
		return $text;
	}

	$rsvp_text = $text;

	// We call this here instead of a few lines up to make sure we know the event ID.
	$rsvp_form_action = htmlspecialchars( rsvp_pro_getCurrentPageURL() );
	rsvp_pro_load_frontend_javascript_variables();

	// See if we should allow people to RSVP, etc.
	if ( ! rsvp_pro_is_event_open( $rsvp_id ) ) {
		$message_open_text = rsvp_pro_get_frontend_string( 'open_text' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_DATE_TEXT ) != '' ) {
			$message_open_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_DATE_TEXT );
		}

		return rsvp_pro_handle_output(
			$text,
			sprintf(
				RSVP_PRO_START_PARA . $message_open_text . RSVP_PRO_END_PARA,
				date_i18n( get_option( 'date_format' ), strtotime( rsvp_pro_get_event_information( $rsvp_id, RSVP_PRO_INFO_OPEN_DATE ) ) )
			)
		);
	}

	if ( rsvp_pro_is_event_closed( $rsvp_id ) ) {
		$message_passed_text = rsvp_pro_get_frontend_string( 'deadline_text' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CLOSE_DATE_TEXT ) !== '' ) {
			$message_passed_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CLOSE_DATE_TEXT );
		}

		return rsvp_pro_handle_output( $text, $message_passed_text );
	}

	$output = '';

	if ( isset( $_REQUEST[ 'rsvpStep' . $rsvp_id ] ) ) {
		switch ( strtolower( $_REQUEST[ 'rsvpStep' . $rsvp_id ] ) ) {
			case 'newattendee':
				return rsvp_pro_handlenewattendee( $output, $text );
			case 'addattendee':
				return rsvp_pro_handlersvp( $output, $text );
			case 'handlersvp':
				$output = rsvp_pro_handlersvp( $output, $text );
				if ( ! empty( $output ) ) {
					return $output;
				}
				break;
			case 'wizardattendee':
				$output = rsvp_pro_frontend_wizard_form( - 1, 'handleRsvp', $text );
				if ( ! empty( $output ) ) {
					return rsvp_pro_handle_output( $text, $output );
				}
				break;
			case 'editattendee':
				$output = rsvp_pro_editAttendee( $output, $text );
				if ( ! empty( $output ) ) {
					return $output;
				}
				break;
			case 'foundattendee':
				$output = rsvp_pro_foundAttendee( $output, $text );
				if ( ! empty( $output ) ) {
					return $output;
				}
				break;
			case 'find':
				$output = rsvp_pro_find( $output, $text );
				if ( ! empty( $output ) ) {
					return $output;
				}
				break;
			case 'attendee_search':
				$output = rsvp_pro_find_attendee_form();

				return rsvp_pro_handle_output( $text, $output );
			case 'newsearch':
			default:
				$current_user = wp_get_current_user();
				if ( ! ( $current_user instanceof WP_User ) ) {
					$current_user = null;
				}

				$tmp_attendee_id = rsvp_pro_autologin_frontend( $rsvp_id );
				if ( $tmp_attendee_id > 0 ) {
					$_POST['attendeeID'] = $tmp_attendee_id;

					return rsvp_pro_foundAttendee( $output, $text );
				} elseif ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_AUTO_LOGIN_ATTENDEE ) == 'Y' ) &&
						   ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) === 'Y' ) &&
						   $current_user && ( $current_user->ID > 0 ) ) {
					$rsvp_pro_saved_form_vars['attendeeFirstName'] = $current_user->user_firstname;
					$rsvp_pro_saved_form_vars['attendeeLastName']  = $current_user->user_lastname;
					$rsvp_pro_saved_form_vars['attendeeEmail']     = $current_user->user_email;

					return rsvp_pro_handlenewattendee( $output, $text );
				} elseif ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CANT_EDIT ) === 'Y' ) &&
						   ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) === 'Y' ) ) {
					return rsvp_pro_handlenewattendee( $output, $text );
				} else {
					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PROMPT_TO_ADD_IF_NOT_FOUND ) === 'Y' ) {
						$rsvp_hide_new_form = true;
					}

					return rsvp_pro_handle_output( $text, rsvp_pro_frontend_greeting() );
				}

				break;
		}
	} else {
		$current_user = wp_get_current_user();
		if ( ! ( $current_user instanceof WP_User ) ) {
			$current_user = null;
		}

		if ( ( isset( $_REQUEST['firstName'] ) && isset( $_REQUEST['lastName'] ) ) ||
			 ( rsvp_pro_require_only_passcode_to_register( $rsvp_id ) && isset( $_REQUEST['passcode'] ) ) ||
			 ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ATTENDEE_LOOKUP_VIA_EMAIL ) === 'Y' ) &&
			   isset( $_REQUEST['email'] ) ) ||
			isset( $_REQUEST['token'] ) ) {
			$output = '';

			return rsvp_pro_find( $output, $text );
		} else {
			$tmp_attendee_id = rsvp_pro_autologin_frontend( $rsvp_id );
			if ( $tmp_attendee_id > 0 ) {
				$_POST['attendeeID'] = $tmp_attendee_id;

				return rsvp_pro_foundAttendee( $output, $text );
			} elseif ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_AUTO_LOGIN_ATTENDEE ) === 'Y' ) &&
					   ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) === 'Y' ) ||
						 rsvp_pro_current_user_auto_enroll( $rsvp_id, $current_user ) ) &&
					   $current_user && ( $current_user->ID > 0 ) ) {
				$rsvp_pro_saved_form_vars['attendeeFirstName'] = $current_user->user_firstname;
				$rsvp_pro_saved_form_vars['attendeeLastName']  = $current_user->user_lastname;
				$rsvp_pro_saved_form_vars['attendeeEmail']     = $current_user->user_email;

				return rsvp_pro_handlenewattendee( $output, $text );
			} elseif ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CANT_EDIT ) === 'Y' ) &&
					   ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) === 'Y' ) ) {
				return rsvp_pro_handlenewattendee( $output, $text );
			} else {
				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PROMPT_TO_ADD_IF_NOT_FOUND ) === 'Y' ) {
					$rsvp_hide_new_form = true;
				}

				return rsvp_pro_handle_output( $text, rsvp_pro_frontend_greeting() );
			}
		}
	}
}

/**
 * Handles displaying the new attendee form.
 *
 * @param  string $output The output that we need to return.
 * @param  string $text The original text of the page.
 *
 * @return string         Returns the text with the new form.
 */
function rsvp_pro_handlenewattendee( $output, $text ) {
	global $rsvp_id;
	$output = rsvp_pro_get_beginning_of_frontend_container();

	$current_user = wp_get_current_user();
	if ( ! ( $current_user instanceof WP_User ) ) {
		$current_user = null;
	}

	if ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_WELCOME ) && ! rsvp_pro_frontend_max_limit_hit( $rsvp_id ) ) {
		if ( '' !== trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_TEXT ) ) ) {
			$output .= RSVP_PRO_START_PARA . trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_TEXT ) ) . RSVP_PRO_END_PARA;
		} else {
			$output .= RSVP_PRO_START_PARA . rsvp_pro_get_frontend_string( 'welcome_text' ) . RSVP_PRO_END_PARA;
		}
	}
	$output .= rsvp_pro_frontend_main_form( 0, 'addAttendee' );
	$output .= RSVP_PRO_END_CONTAINER;

	return rsvp_pro_handle_output( $text, $output );
}

/**
 * Returns the text for if a user can only RSVP once
 *
 * @return [type] [description]
 */
function rsvp_pro_frontend_only_once_text() {
	global $rsvp_id;

	$prompt = "<div>\r\n";
	$text   = rsvp_pro_get_frontend_string( 'rsvp_only_once' );

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_ONLY_ONCE_TEXT ) != '' ) {
		$text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_ONLY_ONCE_TEXT );
	}
	$prompt .= $text;
	$prompt .= "</div>\r\n";

	return $prompt;
}

/**
 * Gets the prompt to edit screen for when someone RSVPs
 *
 * @param  dbo $attendee An attendee row record from the database.
 *
 * @return string           The HTML / Form that will prompt the user to continue with editing their RSVP record.
 */
function rsvp_pro_frontend_prompt_to_edit( $attendee ) {
	global $rsvp_id;
	$rsvp_form_action = htmlspecialchars( rsvp_pro_getCurrentPageURL() );
	$prompt           = "<div>\r\n";
	$edit_greeting    = rsvp_pro_get_frontend_string( 'edit_greeting' );
	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EDIT_PROMPT_TEXT ) !== '' ) {
		$edit_greeting = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EDIT_PROMPT_TEXT );
	}
	$yes_text = rsvp_pro_get_frontend_string( 'yes_text' );
	$no_text  = rsvp_pro_get_frontend_string( 'no_text' );

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_YES_TEXT ) !== '' ) {
		$yes_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_YES_TEXT );
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_TEXT ) !== '' ) {
		$no_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_TEXT );
	}

	$prompt .= sprintf(
		RSVP_PRO_START_PARA . $edit_greeting . RSVP_PRO_END_PARA,
		esc_html( stripslashes( $attendee->firstName ) ),
		esc_html( stripslashes( $attendee->lastName ) )
	);

	$onclick_js = "document.getElementById('rsvpStep" . $rsvp_id . "').value='newsearch';";
	$onclick_js = apply_filters( 'rsvp_pro_edit_prompt_no_onclick', $onclick_js );

	$prompt .= '<form method="post" action="' . $rsvp_form_action . '">' . "\r\n" .
			   '  <input type="hidden" name="rsvp_id" id="rsvp_id" value="' . $rsvp_id . '" />' .
			   '<input type="hidden" name="attendeeID" value="' . $attendee->id . '" id="attendeeID" />
					<input type="hidden" name="rsvpStep' . $rsvp_id . '" id="rsvpStep' . $rsvp_id . '" value="editattendee" />
					<input type="submit" value="' . esc_attr( $yes_text ) . '" onclick="document.getElementById(\'rsvpStep' . $rsvp_id . '\').value=\'editattendee\';" class="rsvpSubmit" />
					<input type="submit" value="' . esc_attr( $no_text ) . '" onclick="' . $onclick_js . '" class="rsvpSubmit"  />
				</form>' . "\r\n";
	$prompt .= RSVP_PRO_END_CONTAINER;

	return $prompt;
}

/**
 * Displays the main RSVP form
 *
 * @param  int    $attendee_id The current attendee id.
 * @param  string $rsvp_step The current RSVP form step.
 *
 * @return string             The HTML that should be displayed to the user.
 */
function rsvp_pro_frontend_main_form( $attendee_id, $rsvp_step = 'handleRsvp' ) {
	global $wpdb, $rsvp_pro_saved_form_vars;
	global $rsvp_id, $my_plugin_file, $has_sub_events;
	$rsvp_form_action = htmlspecialchars( rsvp_pro_getCurrentPageURL() );

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FRONTEND_WIZARD ) === 'Y' ) {
		return rsvp_pro_frontend_wizard_form( $attendee_id, $rsvp_step );
	} else {
		return rsvp_pro_frontend_old_form( $attendee_id, $rsvp_step );
	}
}

/**
 * Handler for the wizard front-end form.
 *
 * @param  int    $attendee_id The current attendee ID.
 * @param  string $rsvp_step The current rsvp step the form is on.
 * @param  string $text The text we need to replace to output to the user.
 *
 * @return string             The new page output with the RSVP form.
 */
function rsvp_pro_frontend_wizard_form( $attendee_id, $rsvp_step = 'handleRsvp', $text = '' ) {
	global $wpdb, $rsvp_pro_saved_form_vars;
	global $rsvp_id, $my_plugin_file, $has_sub_events;

	$rsvp_form_action = htmlspecialchars( rsvp_pro_getCurrentPageURL() );
	// We check for $attendee_id to be less than zero as that will be passed when.
	// we are in one of the next steps of the wizard.
	if ( ( $attendee_id < 0 ) && isset( $_POST['attendeeID'] ) ) {
		$sql = 'SELECT id, firstName, lastName, rsvpStatus
                FROM ' . PRO_ATTENDEES_TABLE . '
                WHERE id = %d AND ( (rsvpEventID = %d) ';

		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR (rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ')';
		}

		$sql .= ')';

		$attendee = $wpdb->get_row( $wpdb->prepare( $sql, $_POST['attendeeID'], $rsvp_id ) );

		if ( ( $attendee !== null ) && ( $attendee->id > 0 ) ) {
			$attendee_id = $attendee->id;
		}
	}

	$form = '';
	$sql  = 'SELECT a.id, firstName, lastName, email, IFNULL(se.rsvpStatus, a.rsvpStatus) as rsvpStatus, 
            note, additionalAttendee, personalGreeting, IFNULL( se.numGuests, a.numGuests) as numGuests, 
            suffix, salutation, passcode 
            FROM ' . PRO_ATTENDEES_TABLE . ' a 
            LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
            WHERE a.id = %d AND ( (a.rsvpEventID = %d) ';

	if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
		$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ')';
	}

	$sql     .= ')';
	$attendee = $wpdb->get_row( $wpdb->prepare( $sql, $rsvp_id, $attendee_id, $rsvp_id ) );

	$associations = rsvp_pro_get_associated_attendees( $rsvp_id, $attendee_id );
	$attendee_ids = array($attendee_id);
	foreach ( $associations as $assc ) {
		$attendee_ids[] = $assc;
	}

	$current_event_id = 0;
	$wizard_step      = 'personalInfo';
	$rsvp_step        = 'wizardattendee';
	$next_wizard_step = 'eventInfo';
	$event_ids        = array();
	$sql              = 'SELECT id FROM ' . PRO_EVENT_TABLE . " e WHERE (id = %d OR parentEventID = %d)
     		AND ((IFNULL(e.event_access, '" . RSVP_PRO_OPEN_EVENT_ACCESS . "') != '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "')
			OR ( (SELECT count(rsvpAttendeeID) FROM " . PRO_EVENT_ATTENDEE_TABLE . ' WHERE rsvpEventID = e.id AND rsvpAttendeeID IN (' . esc_sql( implode(",", $attendee_ids) ) . ') > 0 ))) ORDER BY id ASC';
	$events           = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $rsvp_id ) );
	// Load the array of event ids.
	foreach ( $events as $e ) {
		$event_ids[] = $e->id;
	}
	$need_to_save = false;

	if ( count( $event_ids ) <= 0 ) {
		$need_to_save = true;
	}

	if ( isset( $_POST['wizardStep'] ) && ! empty( $_POST['wizardStep'] ) ) {
		$wizard_step = $_POST['wizardStep'];
		if ( $wizard_step == 'personalInfo' ) {
			// Next step should be event info.
			$next_wizard_step = 'eventInfo';
		} elseif ( $wizard_step == 'eventInfo' ) {
			if ( isset( $_POST['currentEventID'] ) && ( $_POST['currentEventID'] > 0 ) && is_numeric( $_POST['currentEventID'] ) ) {
				$current_event_id = $_POST['currentEventID'];
			}

			$found_next_id = false;
			// Loop through the array and see if we are at the end or what.
			for ( $i = 0; $i < count( $event_ids ); ++ $i ) {
				if ( $event_ids[ $i ] > $current_event_id ) {
					$current_event_id = $event_ids[ $i ];
					$found_next_id    = true;
					if ( $i === ( count( $event_ids ) - 1 ) ) {
						$need_to_save = true;
					}
					break;
				}
			}

			$next_wizard_step = 'eventInfo';
		}
	}

	if ( $need_to_save ) {
		if ( $attendee_id <= 0 ) {
			$rsvp_step = 'addattendee';
		} else {
			$rsvp_step = 'handlersvp';
		}
	}

	$form  = "<form id=\"rsvpForm\" name=\"rsvpForm\" method=\"post\" action=\"$rsvp_form_action\" autocomplete=\"off\" enctype=\"multipart/form-data\">";
	$form .= '  <input type="hidden" name="rsvp_id" id="rsvp_id" value="' . $rsvp_id . '" />';
	$form .= '	<input type="hidden" name="attendeeID" id="attendeeID" value="' . $attendee_id . '" />';
	$form .= "	<input type=\"hidden\" name=\"rsvpStep$rsvp_id\" value=\"$rsvp_step\" />";
	$form .= "	<input type=\"hidden\" name=\"wizardStep\" id=\"wizardStep\" value=\"$next_wizard_step\" />";
	$form .= "	<input type=\"hidden\" name=\"currentEventID\" value=\"$current_event_id\" />";

	$reserved_items = array( 'attendeeID', 'rsvpStep' . $rsvp_id, 'wizardStep', 'currentEventID' );
	foreach ( $_POST as $key => $val ) {
		if ( ! in_array( $key, $reserved_items, true ) ) {
			if ( is_array( $_POST[ $key ] ) ) {
				foreach ( $val as $v ) {
					$form .= ' <input type="hidden" name="' . esc_html( $key ) . '[]" value="' . esc_html( $v ) . '" />';
				}
			} else {
				$form .= ' <input type="hidden" name="' . esc_html( $key ) . '" value="' . esc_html( $val ) . '" />';
			}
		}
	}

	if ( isset( $_FILES ) ) {
		require_once( ABSPATH . 'wp-admin/includes/image.php' );
		require_once( ABSPATH . 'wp-admin/includes/file.php' );
		require_once( ABSPATH . 'wp-admin/includes/media.php' );
		foreach ( $_FILES as $key => $val ) {
			if ( is_uploaded_file( $_FILES[ $key ]['tmp_name'] ) ) {
				$new_file_id = media_handle_upload( $key, 0 );
				if ( is_int( $new_file_id ) ) {
					$transient_name = 'rsvp_tmp_file_import_' . uniqid();
					set_transient( $transient_name, $new_file_id, 6 * HOUR_IN_SECONDS );
					$form .= ' <input type="hidden" name="temp' . $key . '" value="' . esc_attr($transient_name) . '" />';
				}
			}
		}
	}

	if ( $wizard_step !== 'personalInfo' ) {
		if ( $wizard_step === 'eventInfo' ) {
			$form .= rsvp_pro_frontend_wizard_eventForm( $current_event_id, $attendee_id );
		} else {
			$form .= rsvp_pro_frontend_wizard_personalInfo( $attendee, $attendee_id );
		}
	} else {
		// Default first page.
		$form .= rsvp_pro_frontend_wizard_personalInfo( $attendee, $attendee_id );
	}

	if ( $need_to_save && ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_GDPR_QUESTION ) ) ) {
		$gdpr_text = rsvp_pro_get_frontend_string( 'gdpr_question' );
		if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_QUESTION_TEXT ) ) {
			$gdpr_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_QUESTION_TEXT );
		}

		$gdpr_required = esc_html__('This field is required','rsvp-pro-plugin');
		if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_JS_MESSAGE ) ) {
			$gdpr_required = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_JS_MESSAGE );
		}
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpBorderTop' ) . '<div>' .
				 '<input type="checkbox" name="gdpr_question" id="gdpr_question" value="Y" required data-msg-required="' . esc_attr( $gdpr_required ) . '"/> ' .
				 '<label for="gdpr_question">' . $gdpr_text . '</label></div>' .
				 RSVP_PRO_END_FORM_FIELD;
	}

	if ( $need_to_save && ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_RECAPTCHA ) ) ) {
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpCaptchaContainer' ) .
				 '<div class="g-recaptcha" data-sitekey="' . esc_attr( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RECAPTCHA_SITE_KEY ) ) . '" id="rsvpCaptcha"></div>' .
				 RSVP_PRO_END_FORM_FIELD;
	}

	if ( $need_to_save && ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_TURNSTILE ) ) ) {
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpCaptchaContainer' ) .
				 '<div class="rsvp-pro-turnstile" data-sitekey="' . esc_attr( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_TURNSTILE_SITE_KEY ) ) . '" id="rsvpTurnstile"></div>' .
				 RSVP_PRO_END_FORM_FIELD;
	}

	$button_text = rsvp_pro_get_frontend_string( 'next_text' );
	if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NEXT_BUTTON_TEXT ) ) !== '' ) {
		$button_text = stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NEXT_BUTTON_TEXT ) );
	}

	$form       .= '<p class="rsvpParagraph rsvpSubmitContainer">' . "<input type=\"submit\" value=\"$button_text\" class=\"rsvpSubmit\" />" . RSVP_PRO_END_PARA;
	$simpleNonce = WPSimpleNonce::createNonce( 'rsvp_fe_form' );
	$form       .= '  <input type="hidden" name="rsvp_nonce_name" value="' . $simpleNonce['name'] . '" />';
	$form       .= '  <input type="hidden" name="rsvp_nonce_value" value="' . $simpleNonce['value'] . '" />';
	$form       .= "</form>\r\n";
	$form       .= rsvp_pro_display_modify_registration_link( $attendee_id );

	return $form;
}

/**
 * Handles display and logic when using the old style of a form with everything on one page.
 *
 * @param  int    $attendee_id The attendee identifier for the main person RSVP'ing.
 * @param  string $rsvp_step The current step the person is on.
 *
 * @return string             The HTML that should be displayed to the user.
 */
function rsvp_pro_frontend_old_form( $attendee_id, $rsvp_step = 'handleRsvp' ) {
	global $wpdb, $rsvp_pro_saved_form_vars;
	global $rsvp_id, $my_plugin_file, $has_sub_events;

	$rsvp_form_action = htmlspecialchars( rsvp_pro_getCurrentPageURL() );
	$rsvp_form_js_ids = array();
	$sql              = 'SELECT a.id, firstName, lastName, email, 
                IFNULL(se.rsvpStatus, a.rsvpStatus) as rsvpStatus, note, additionalAttendee, personalGreeting, 
                IFNULL(se.numGuests, a.numGuests) as numGuests, suffix, salutation, passcode, IFNULL(se.plus_one, a.plus_one) AS plus_one 
            FROM ' . PRO_ATTENDEES_TABLE . ' a 
            LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
            WHERE a.id = %d AND ( (a.rsvpEventID = %d) ';

	if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
		$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
	}

	$sql .= ')';

	$attendee = $wpdb->get_row( $wpdb->prepare( $sql, $rsvp_id, $attendee_id, $rsvp_id ) );

	$sql = 'SELECT id FROM ' . PRO_ATTENDEES_TABLE . '
			WHERE (id IN (SELECT attendeeID FROM ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' WHERE associatedAttendeeID = %d)
			OR id in (SELECT associatedAttendeeID FROM ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' WHERE attendeeID = %d))
			AND ( (rsvpEventID = %d) ';

	if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
		$sql .= ' OR (rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ')';
	}

	$sql      .= ' )';
	$new_rsvps = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $attendee_id, $rsvp_id ) );

	$waitlist_text    = rsvp_pro_get_frontend_string( 'waitlist_text' );
	$no_response_text = rsvp_pro_get_frontend_string( 'noresponse_text' );
	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_RESPONSE_TEXT ) !== '' ) {
		$no_response_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_RESPONSE_TEXT );
	}
	$num_guests = get_number_additional( $rsvp_id, $attendee );

	$yes_verbiage      = rsvp_pro_get_yes_verbiage( $rsvp_id );
	$no_verbiage       = rsvp_pro_get_no_verbiage( $rsvp_id );
	$waitlist_verbiage = rsvp_pro_get_waitlist_verbiage( $rsvp_id );
	$maybe_verbiage    = rsvp_pro_get_maybe_verbiage( $rsvp_id );
	$plus_one_verbiage = rsvp_pro_get_plus_one_verbiage( $rsvp_id );
	$max_limit_hit     = rsvp_pro_frontend_max_limit_hit( $rsvp_id );

	$note_verbiage = ( ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOTE_VERBIAGE ) ) !== '' ) ? rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOTE_VERBIAGE ) :
		rsvp_pro_get_frontend_string( 'note_text' ) );

	$form  = "<form id=\"rsvpForm\" name=\"rsvpForm\" method=\"post\" action=\"$rsvp_form_action\" autocomplete=\"off\" enctype=\"multipart/form-data\" >\r\n";
	$form .= '  <input type="hidden" name="rsvp_id" id="rsvp_id" value="' . $rsvp_id . '" />';
	$form .= '	<input type="hidden" name="attendeeID" id="attendeeID" value="' . $attendee_id . "\" />\r\n";
	$form .= "	<input type=\"hidden\" name=\"rsvpStep$rsvp_id\" value=\"$rsvp_step\" />\r\n";

	if ( $max_limit_hit ) {
		$form .= rsvp_pro_handle_max_limit_reached_message( $rsvp_id );
		$form .= rsvp_pro_handle_waitlist_message( $rsvp_id );
	}

	if ( ! empty( $attendee->personalGreeting ) ) {
		$form .= rsvp_pro_beginning_form_field( 'rsvpCustomGreeting', '' ) . nl2br( stripslashes_deep( $attendee->personalGreeting ) ) . RSVP_PRO_END_FORM_FIELD;
	}

	if ( does_user_have_access_to_event( $rsvp_id, $attendee_id ) ) :
		$form .= RSVP_PRO_START_PARA;
		if ( ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_HIDE ) ) &&
			 ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_RSVP_QUESTION ) ) ) {
			if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_QUESTION ) ) !== '' ) {
				$form .= trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_QUESTION ) );
			} else {
				$form .= rsvp_pro_get_frontend_string( 'rsvp_question' );
			}
		}
		$form .= RSVP_PRO_END_PARA;

		$user_rsvp_status = 'NoResponse';
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DEFAULT_RSVP_VALUE ) !== '' ) {
			$user_rsvp_status = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DEFAULT_RSVP_VALUE );
			$user_rsvp_status = ucfirst( $user_rsvp_status );
		}

		// Handle the case where we have hit the limit and the default status is "Yes" which it now can't be.
		if ( $max_limit_hit && ( 'Yes' === $user_rsvp_status ) ) {
			$user_rsvp_status = 'Waitlist';
		}

		if ( isset( $rsvp_pro_saved_form_vars['mainRsvp'] ) ) {
			if ( $rsvp_pro_saved_form_vars['mainRsvp'] === 'Y' ) {
				$user_rsvp_status = 'Yes';
			} elseif ( $rsvp_pro_saved_form_vars['mainRsvp'] === 'N' ) {
				$user_rsvp_status = 'No';
			} elseif ( $rsvp_pro_saved_form_vars['mainRsvp'] === 'W' ) {
				$user_rsvp_status = 'Waitlist';
			} elseif ( $rsvp_pro_saved_form_vars['mainRsvp'] === 'M' ) {
				$user_rsvp_status = 'Maybe';
			} elseif ( $rsvp_pro_saved_form_vars['mainRsvp'] === 'PlusOne' ) {
				$user_rsvp_status = 'PlusOne';
			}
		} elseif ( isset( $attendee ) && ( strtolower( $attendee->rsvpStatus ) !== 'noresponse' ) && ( $attendee->rsvpStatus !== '' ) ) {
			$user_rsvp_status = $attendee->rsvpStatus;
		} elseif ( isset( $_REQUEST['rsvpStatus'] ) && rsvp_pro_is_allowed_status( $_REQUEST['rsvpStatus'] ) ) {
			$user_rsvp_status = $_REQUEST['rsvpStatus'];
		}

		$required_rsvp = '';
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_REQUIRED ) === 'Y' ) {
			$required_rsvp = ' required';
		}

		if ( $max_limit_hit ) {
			$required_rsvp .= ' disabled="true"';
		}

		$rsvp_js_id               = uniqid();
		$rsvp_form_js_ids['main'] = $rsvp_js_id;
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_HIDE ) === 'Y' ) {
			$form .= '<input type="hidden" name="mainRsvp" value="' . rsvp_pro_translate_status_to_form_value( $user_rsvp_status ) . '" data-rsvp-js-id="' . $rsvp_js_id . '" class="rsvpStatusInput" />';
		} else {
			$yes_additional_attribs = array();
			if ( $max_limit_hit && ( 'Yes' !== $user_rsvp_status ) ) {
				$yes_additional_attribs['style'] = 'display: none;';
			}
			$form .= '<div class="rsvpMainRsvpQuestionContainer">';
			$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea', $yes_additional_attribs ) .
					 '<input type="radio" name="mainRsvp" value="Y" id="mainRsvpY" data-rsvp-js-id="' . $rsvp_js_id . '" ' .
					 ( ( ( 'Yes' === $user_rsvp_status ) && ( ! isset( $attendee ) || ( $attendee->plus_one !== 'Y' ) ) ) ? 'checked="checked"' : '' ) . " $required_rsvp class=\"rsvpStatusInput\" /> <label for=\"mainRsvpY\">" . $yes_verbiage . '</label>' .
					 RSVP_PRO_END_FORM_FIELD;

			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_MAYBE ) === 'Y' ) ) {
				$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
						 '<input type="radio" name="mainRsvp" value="M" id="mainRsvpMaybe" data-rsvp-js-id="' . $rsvp_js_id . '" ' .
						 ( ( ( 'Maybe' === $user_rsvp_status ) ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
						 '<label for="mainRsvpMaybe">' . $maybe_verbiage . '</label>' .
						 RSVP_PRO_END_FORM_FIELD;
			}

			$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
					 '<input type="radio" name="mainRsvp" value="N" id="mainRsvpN" data-rsvp-js-id="' . $rsvp_js_id . '" ' .
					 ( ( ( 'No' === $user_rsvp_status ) ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
					 '<label for="mainRsvpN">' . $no_verbiage . '</label>' . RSVP_PRO_END_FORM_FIELD;

			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) === 'Y' ) && rsvp_pro_frontend_max_limit_hit( $rsvp_id ) ) {
				$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
						'<input type="radio" name="mainRsvp" value="W" id="mainRsvpWaitlist" data-rsvp-js-id="' . $rsvp_js_id . '" ' .
						( ( ( 'Waitlist' === $user_rsvp_status ) ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
						'<label for="mainRsvpWaitlist">' . $waitlist_verbiage . '</label>' .
						RSVP_PRO_END_FORM_FIELD;
			}

			if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PLUS_ONE_ENABLED ) ) {
				$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
						'<input type="radio" name="mainRsvp" id="mainPlusone" data-rsvp-js-id="' . $rsvp_js_id . '" value="PlusOne" ' .
						( ( isset( $attendee ) && ( $user_rsvp_status === 'PlusOne' ) ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" />' .
						' <label for="mainPlusone">' . $plus_one_verbiage . '</label> ' .
						RSVP_PRO_END_FORM_FIELD;
			}

			$form .= '</div>';
		}
	endif;

	if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_UNDER_RSVP_TEXT ) ) {
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpTextUnderRsvpArea' ) .
				RSVP_PRO_START_PARA . rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_UNDER_RSVP_TEXT ) . RSVP_PRO_END_PARA .
				RSVP_PRO_END_FORM_FIELD;
	}

	// New Attendee fields when open registration is allowed.
	if ( ( $attendee_id <= 0 ) || ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_LAST_EDITABLE ) === 'Y' ) ) {
		$first_name = isset( $rsvp_pro_saved_form_vars['attendeeFirstName'] ) ? $rsvp_pro_saved_form_vars['attendeeFirstName'] : '';
		$last_name  = isset( $rsvp_pro_saved_form_vars['attendeeLastName'] ) ? $rsvp_pro_saved_form_vars['attendeeLastName'] : '';

		if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SALUTATION ) ) {
			$label = rsvp_pro_get_frontend_string( 'salutation_text' );
			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SALUTATION_LABEL ) !== '' ) {
				$label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SALUTATION_LABEL );
			}

			$form .= rsvp_pro_beginning_form_field( '', 'rsvpBorderTop' ) .
					 '<label for="mainSalutation">' . $label . '</label>' .
					 '<select name="mainSalutation" id="mainSalutation" size="1"><option value="">--</option>';

			$salutations         = rsvp_pro_get_salutation_options( $rsvp_id );
			$attendee_salutation = '';
			if ( $attendee != null ) {
				$attendee_salutation = $attendee->salutation;
			}

			if ( isset( $rsvp_pro_saved_form_vars['mainSalutation'] ) ) {
				$attendee_salutation = $rsvp_pro_saved_form_vars['mainSalutation'];
			}
			$attendee_salutation = trim( $attendee_salutation );
			foreach ( $salutations as $s ) {
				$s = trim( $s );
				$form .= '<option value="' . esc_html( $s ) . '" ' . ( ( $s === $attendee_salutation ) ? 'selected="selected"' : '' ) . '>' . esc_html( $s ) . '</option>';
			}

			$form .= '</select>' . RSVP_PRO_END_FORM_FIELD;
		}

		if ( ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_LAST_EDITABLE ) ) &&
			 ( null !== $attendee ) ) {
			$first_name = stripslashes( $attendee->firstName );
			$last_name  = stripslashes( $attendee->lastName );
		}

		if ( isset( $rsvp_pro_saved_form_vars['attendeeFirstName'] ) ) {
			$first_name = $rsvp_pro_saved_form_vars['attendeeFirstName'];
		}

		if ( isset( $rsvp_pro_saved_form_vars['attendeeLastName'] ) ) {
			$last_name = $rsvp_pro_saved_form_vars['attendeeLastName'];
		}

		$first_name_label = rsvp_pro_get_frontend_string( 'first_name_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_NAME_LABEL ) !== '' ) {
			$first_name_label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_NAME_LABEL );
		}

		$last_name_label = rsvp_pro_get_frontend_string( 'last_name_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_LABEL ) !== '' ) {
			$last_name_label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_LABEL );
		}

		$form .= RSVP_PRO_START_PARA;
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpMainAttendeeFirstNameContainer' ) .
				 '<label for="attendeeFirstName">' . $first_name_label . '</label>' .
				 '<input type="text" name="attendeeFirstName" id="attendeeFirstName" value="' . esc_html( $first_name ) . '" required />' .
				 RSVP_PRO_END_FORM_FIELD;
		$form .= RSVP_PRO_END_PARA;

		$form .= RSVP_PRO_START_PARA;
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpMainAttendeeLastNameContainer' ) .
				 '<label for="attendeeLastName">' . $last_name_label . '</label>' .
				 '<input type="text" name="attendeeLastName" id="attendeeLastName" value="' . esc_html( $last_name ) . '" ' . ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_NOT_REQUIRED ) !== 'Y' ) ? 'required' : '' ) . ' />' .
				 RSVP_PRO_END_FORM_FIELD;
		$form .= RSVP_PRO_END_PARA;

		if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SUFFIX ) ) {
			$label           = rsvp_pro_get_frontend_string( 'suffix_label' );
			$attendee_suffix = ( isset( $attendee ) ) ? stripslashes_deep( $attendee->suffix ) : '';
			if ( isset( $rsvp_pro_saved_form_vars['mainSuffix'] ) ) {
				$attendee_suffix = $rsvp_pro_saved_form_vars['mainSuffix'];
			}

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SUFFIX_LABEL ) !== '' ) {
				$label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SUFFIX_LABEL );
			}

			$form .= rsvp_pro_beginning_form_field( '', '' ) .
					 '<label for="mainSuffix">' . $label . '</label>' .
					 '<input type="text" name="mainSuffix" id="mainSuffix" value="' . esc_html( $attendee_suffix ) . '" />' .
					 RSVP_PRO_END_FORM_FIELD;
		}
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_EDITABLE ) === 'Y' ) {
		$passcode = isset( $attendee ) ? stripslashes( $attendee->passcode ) : '';

		if ( isset( $rsvp_pro_saved_form_vars['attendeePasscode'] ) ) {
			$passcode = $rsvp_pro_saved_form_vars['attendeePasscode'];
		}

		$passcode_label = rsvp_pro_get_frontend_string( 'attendee_passcode_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_EDITABLE_LABEL ) != '' ) {
			$passcode_label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_EDITABLE_LABEL );
		}
		$form .= RSVP_PRO_START_PARA;
		$form .= rsvp_pro_beginning_form_field( '', '' ) .
				 '<label for="attendeePasscode"> ' . $passcode_label . '</label>' .
				 '<input type="text" name="attendeePasscode" id="attendeePasscode" value="' . esc_html( $passcode ) . '" class="rsvpPasscodeField" data-rule-rsvpProPasscodeUnique="true" />' .
				 RSVP_PRO_END_FORM_FIELD;
		$form .= RSVP_PRO_END_PARA;
	}

	if ( ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_HIDE_EMAIL_FIELD ) ) ||
		 ( ( $attendee_id <= 0 ) && ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ATTENDEE_LOOKUP_VIA_EMAIL ) === 'Y' ) ) ) {
		$label = rsvp_pro_get_frontend_string( 'email_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_LABEL ) !== '' ) {
			$label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_LABEL );
		}

		$js_validation = rsvp_pro_get_frontend_string( 'javascript_email_validation' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_JS_MESSAGE ) !== '' ) {
			$js_validation = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_JS_MESSAGE );
		}

		$form .= RSVP_PRO_START_PARA . rsvp_pro_beginning_form_field( '', 'rsvpMainAttendeeEmailContainer' ) .
				'<label for="mainEmail">' . $label . '</label>' .
				'<input type="text" name="mainEmail" id="mainEmail" value="' .
				( ( isset( $rsvp_pro_saved_form_vars['mainEmail'] ) ) ? esc_html( $rsvp_pro_saved_form_vars['mainEmail'] ) : ( isset( $attendee ) ? esc_html( $attendee->email ) : '' ) ) . '" ' .
				( ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_REQUIRED ) ) ? 'required data-rule-email="true"' : '' ) . '
         class="rsvpEmailField" data-rule-rsvpProEmailUnique="true" data-msg-required="' . esc_attr( $js_validation ) . '" />' . RSVP_PRO_END_FORM_FIELD . RSVP_PRO_END_PARA;
	}

	$form .= rsvp_pro_build_sub_event_main_form( $attendee_id, 'main', $rsvp_form_js_ids, true );
	$form .= rsvp_pro_buildAdditionalQuestions( $attendee_id, 'main', true, $rsvp_form_js_ids );

	// Add in group questions.
	$form .= rsvp_pro_beginning_form_field( '', 'rsvpBorderTop' );
	$form .= RSVP_PRO_END_FORM_FIELD;

	if ( does_user_have_access_to_event( $rsvp_id, $attendee_id ) && ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_NOTE ) !== 'Y' ) ) {
		$tmp_note = '';
		if ( ( null !== $attendee ) && ! empty( $attendee->note ) ) {
			$tmp_note = stripslashes( $attendee->note );
		}

		if ( isset( $rsvp_pro_saved_form_vars['rsvp_note'] ) ) {
			$tmp_note = $rsvp_pro_saved_form_vars['rsvp_note'];
		}

		$form .= RSVP_PRO_START_PARA . $note_verbiage . RSVP_PRO_END_PARA .
				rsvp_pro_beginning_form_field( '', '' ) .
				'<textarea name="rsvp_note" id="rsvp_note" rows="7" cols="50">' . esc_html( $tmp_note ) . '</textarea>' . RSVP_PRO_END_FORM_FIELD;
	}

	$sql = 'SELECT id, firstName, lastName, email, personalGreeting, 
        rsvpStatus, salutation, suffix, passcode FROM ' . PRO_ATTENDEES_TABLE . '
	   WHERE (id IN (SELECT attendeeID FROM ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' WHERE associatedAttendeeID = %d)
	   OR id in (SELECT associatedAttendeeID FROM ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' WHERE attendeeID = %d) OR
	   id IN (SELECT waa1.attendeeID FROM ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' waa1
	   INNER JOIN ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' waa2 ON waa2.attendeeID = waa1.attendeeID  OR
	   waa1.associatedAttendeeID = waa2.attendeeID
	   WHERE waa2.associatedAttendeeID = %d AND waa1.attendeeID <> %d)) AND ( (rsvpEventID = %d) ';

	if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
		$sql .= ' OR (rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ')';
	}

	$sql .= ')';

	$associations = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $attendee_id, $attendee_id, $attendee_id, $rsvp_id ) );
	if ( count( $associations ) > 0 ) {
		$message = rsvp_pro_get_frontend_string( 'associated_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ASSOCIATED_MESSAGE ) != '' ) {
			$message = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ASSOCIATED_MESSAGE );
		}

		$form .= '<h3>' . $message . '</h3>';
		foreach ( $associations as $a ) {
			if ( $a->id !== $attendee_id ) {
				$form            .= "<div class=\"rsvpAdditionalAttendee\">\r\n";
				$form            .= "<div class=\"rsvpAdditionalAttendeeQuestions\">\r\n";
				$rsvp_form_js_ids = array();

				if ( does_user_have_access_to_event( $rsvp_id, $a->id ) ) {
					$associated_yes_verbiage      = apply_filters( 'rsvp_yes_associated', $yes_verbiage, $a, $rsvp_id );
					$associated_maybe_verbiage    = apply_filters( 'rsvp_maybe_associated', $maybe_verbiage, $a, $rsvp_id );
					$associated_no_verbiage       = apply_filters( 'rsvp_no_associated', $no_verbiage, $a, $rsvp_id );
					$associated_waitlist_verbiage = apply_filters( 'rsvp_waitlist_associated', $waitlist_verbiage, $a, $rsvp_id );
					$associated_no_response_text  = apply_filters( 'rsvp_no_response_associated', $no_response_text, $a, $rsvp_id );

					$required_rsvp = '';
					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_REQUIRED ) === 'Y' ) {
						$required_rsvp = ' required';
					}

					if ( rsvp_pro_frontend_max_limit_hit( $rsvp_id ) ) {
						$form          .= rsvp_pro_handle_max_limit_reached_message( $rsvp_id );
						$form          .= rsvp_pro_handle_waitlist_message( $rsvp_id );
						$required_rsvp .= ' disabled="true"';
					}

					$greeting = rsvp_pro_get_frontend_string( 'associated_greeting' );
					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ASSOCIATED_ATTENDEE_GREETING ) !== '' ) {
						$greeting = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ASSOCIATED_ATTENDEE_GREETING );
					}

					if ( strpos( $greeting, '%s' ) !== false ) {
						$greeting = sprintf( $greeting, esc_html( stripslashes( $a->firstName . ' ' . $a->lastName ) ) );
					}

					$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpGreeting' ) . '<h4>' . $greeting . '</h4>' . RSVP_PRO_END_FORM_FIELD;

					if ( ! empty( $a->personalGreeting ) ) {
						$form .= RSVP_PRO_START_PARA . nl2br( $a->personalGreeting ) . RSVP_PRO_END_PARA;
					}

					$user_rsvp_status = 'NoResponse';
					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DEFAULT_RSVP_VALUE ) !== '' ) {
						$user_rsvp_status = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DEFAULT_RSVP_VALUE );
						$user_rsvp_status = ucfirst( $user_rsvp_status );
					}

					if ( isset( $rsvp_pro_saved_form_vars['attending' . $a->id ] ) ) {
						if ( $rsvp_pro_saved_form_vars['attending' . $a->id ] === 'Y' ) {
							$user_rsvp_status = 'Yes';
						} elseif ( $rsvp_pro_saved_form_vars['attending' . $a->id ] === 'N' ) {
							$user_rsvp_status = 'No';
						} elseif ( $rsvp_pro_saved_form_vars['attending' . $a->id ] === 'W' ) {
							$user_rsvp_status = 'Waitlist';
						} elseif ( $rsvp_pro_saved_form_vars['attending' . $a->id ] === 'M' ) {
							$user_rsvp_status = 'Maybe';
						} elseif ( $rsvp_pro_saved_form_vars['attending' . $a->id ] === 'PlusOne' ) {
							$user_rsvp_status = 'PlusOne';
						}
					} elseif ( isset( $a ) && ( strtolower( $a->rsvpStatus ) !== 'noresponse' ) && ! empty( $a->rsvpStatus ) ) {
						$user_rsvp_status = $a->rsvpStatus;
					} elseif ( isset( $_REQUEST['rsvpStatus'] ) && rsvp_pro_is_allowed_status( $_REQUEST['rsvpStatus'] ) ) {
						$user_rsvp_status = $_REQUEST['rsvpStatus'];
					}

					$rsvp_js_id               = uniqid();
					$rsvp_form_js_ids['main'] = $rsvp_js_id;
					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_HIDE ) === 'Y' ) {
						$form .= '<input type="hidden" name="attending' . $a->id . '" value="' . rsvp_pro_translate_status_to_form_value( $user_rsvp_status ) . '" data-rsvp-js-id="' . $rsvp_js_id . '" class="rsvpStatusInput" /> ';
					} else {
						$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
								 '<input type="radio" name="attending' . $a->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="Y" id="attending' . $a->id . 'Y" ' . ( ( 'Yes' === $user_rsvp_status ) ? 'checked="checked"' : '' ) . " $required_rsvp class=\"rsvpStatusInput\" /> " .
								 '<label for="attending' . $a->id . "Y\">$associated_yes_verbiage</label>" . RSVP_PRO_END_FORM_FIELD;

						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_MAYBE ) === 'Y' ) {
							$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
									 '<input type="radio" name="attending' . $a->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="M" id="attending' . $a->id . 'Maybe" ' . ( ( $user_rsvp_status === 'Maybe' ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
									 '<label for="attending' . $a->id . 'Maybe">' . $associated_maybe_verbiage . '</label>' .
									 RSVP_PRO_END_FORM_FIELD;
						}

						$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
								 '<input type="radio" name="attending' . $a->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="N" id="attending' . $a->id . 'N" ' . ( ( 'No' === $user_rsvp_status ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
								 '<label for="attending' . $a->id . "N\">$associated_no_verbiage</label>" . RSVP_PRO_END_FORM_FIELD;

						if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) === 'Y' ) && rsvp_pro_frontend_max_limit_hit( $rsvp_id ) ) {
							$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
									 '<input type="radio" name="attending' . $a->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="W" id="attending' . $a->id . 'Waitlist" ' . ( ( $user_rsvp_status === 'Waitlist' ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
									 '<label for="attending' . $a->id . 'Waitlist">' . $associated_waitlist_verbiage . '</label>' .
									 RSVP_PRO_END_FORM_FIELD;
						}

						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_NORESPONSE_FOR_ASSOCIATED ) === 'Y' ) {
							$form .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) . '<input type="radio" name="attending' . $a->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="NoResponse" id="attending' . $a->id . 'NoResponse" ' . ( ( 'NoResponse' === $user_rsvp_status ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
									 '<label for="attending' . $a->id . "NoResponse\">$associated_no_response_text</label>" . RSVP_PRO_END_FORM_FIELD;
						}
					}

					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SALUTATION ) === 'Y' ) {
						$label = rsvp_pro_get_frontend_string( 'salutation_text' );
						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SALUTATION_LABEL ) !== '' ) {
							$label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SALUTATION_LABEL );
						}

						$tmp_salutation = $a->salutation;

						if ( isset( $rsvp_pro_saved_form_vars['attending' . $a->id . 'Salutation'] ) ) {
							$tmp_salutation = $rsvp_pro_saved_form_vars['attending' . $a->id . 'Salutation'];
						}
						$tmp_salutation = trim( $tmp_salutation );

						$form .= rsvp_pro_beginning_form_field( '', 'rsvpBorderTop' ) .
								 '<label for="attending' . $a->id . 'Salutation">' . $label . '</label>' .
								 '<select name="attending' . $a->id . 'Salutation" id="attending' . $a->id . 'Salutation" size="1"><option value="">--</option>';

						$salutations = rsvp_pro_get_salutation_options( $rsvp_id );
						foreach ( $salutations as $s ) {
							$s = trim( $s );
							$form .= '<option value="' . esc_html( $s ) . '" ' . ( ( $s === $tmp_salutation ) ? 'selected="selected"' : '' ) . '>' . esc_html( $s ) . '</option>';
						}

						$form .= '</select>' . RSVP_PRO_END_FORM_FIELD;
					}

					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_LAST_EDITABLE ) === 'Y' ) {
						$first_name_label = rsvp_pro_get_frontend_string( 'first_name_label' );
						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_NAME_LABEL ) !== '' ) {
							$first_name_label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_NAME_LABEL );
						}

						$last_name_label = rsvp_pro_get_frontend_string( 'last_name_label' );
						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_LABEL ) !== '' ) {
							$last_name_label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_LABEL );
						}

						$tmp_first_name = $a->firstName;
						$tmp_last_name  = $a->lastName;

						if ( isset( $rsvp_pro_saved_form_vars['attending' . $a->id . 'FirstName'] ) ) {
							$tmp_first_name = $rsvp_pro_saved_form_vars['attending' . $a->id . 'FirstName'];
						}

						if ( isset( $rsvp_pro_saved_form_vars['attending' . $a->id . 'LastName'] ) ) {
							$tmp_last_name = $rsvp_pro_saved_form_vars['attending' . $a->id . 'LastName'];
						}

						$form .= RSVP_PRO_START_PARA;
						$form .= rsvp_pro_beginning_form_field( '', '' ) .
								 '<label for="attending' . $a->id . 'FirstName">' . $first_name_label . '</label>' .
								 '<input type="text" name="attending' . $a->id . 'FirstName" id="attending' . $a->id . 'FirstName" value="' . esc_html( stripslashes( $tmp_first_name ) ) . '" required />' .
								 RSVP_PRO_END_FORM_FIELD;
						$form .= RSVP_PRO_END_PARA;

						$form .= RSVP_PRO_START_PARA;
						$form .= rsvp_pro_beginning_form_field( '', '' ) .
								 '<label for="attending' . $a->id . 'LastName">' . $last_name_label . '</label>' .
								 '<input type="text" name="attending' . $a->id . 'LastName" id="attending' . $a->id . 'LastName" value="' . esc_html( stripslashes( $tmp_last_name ) ) . '" ' . ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_NOT_REQUIRED ) !== 'Y' ) ? 'required' : '' ) . ' />' .
								 RSVP_PRO_END_FORM_FIELD;
						$form .= RSVP_PRO_END_PARA;
					}

					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SUFFIX ) === 'Y' ) {
						$label = rsvp_pro_get_frontend_string( 'suffix_label' );
						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SUFFIX_LABEL ) !== '' ) {
							$label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SUFFIX_LABEL );
						}

						$tmp_suffix = stripslashes( $a->suffix );
						if ( isset( $rsvp_pro_saved_form_vars['attending' . $a->id . 'Suffix'] ) ) {
							$tmp_suffix = $rsvp_pro_saved_form_vars['attending' . $a->id . 'Suffix'];
						}

						$form .= RSVP_PRO_START_PARA . rsvp_pro_beginning_form_field( '', '' ) .
								'<label for="attending' . $a->id . 'Suffix">' . $label . '</label>' .
								'<input type="text" name="attending' . $a->id . 'Suffix" id="attending' . $a->id . 'Suffix" value="' . esc_html( $tmp_suffix ) . '" />' .
								RSVP_PRO_END_FORM_FIELD . RSVP_PRO_END_PARA;
					}

					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_EDITABLE ) === 'Y' ) {
						$passcode = stripslashes( $a->passcode );

						if ( isset( $rsvp_pro_saved_form_vars['attending' . $a->id . 'Passcode'] ) ) {
							$pascode = $rsvp_pro_saved_form_vars['attending' . $a->id . 'Passcode'];
						}

						$passcode_label = rsvp_pro_get_frontend_string( 'attendee_passcode_label' );
						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_EDITABLE_LABEL ) != '' ) {
							$passcode_label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_EDITABLE_LABEL );
						}
						$form .= RSVP_PRO_START_PARA;
						$form .= rsvp_pro_beginning_form_field( '', '' ) .
								'<label for="attending' . $a->id . 'Passcode"> ' . $passcode_label . '</label>' .
								'<input type="text" name="attending' . $a->id . 'Passcode" id="attending' . $a->id . 'Passcode" value="' . esc_html( $passcode ) . '" class="rsvpPasscodeField" data-rule-rsvpProPasscodeUnique="true" />' .
								RSVP_PRO_END_FORM_FIELD;
						$form .= RSVP_PRO_END_PARA;
					}

					if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_HIDE_EMAIL_FIELD ) !== 'Y' ) {
						$label = rsvp_pro_get_frontend_string( 'email_label' );
						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_LABEL ) !== '' ) {
							$label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_LABEL );
						}

						$js_validation = rsvp_pro_get_frontend_string( 'javascript_email_validation' );
						if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_JS_MESSAGE ) !== '' ) {
							$js_validation = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_JS_MESSAGE );
						}

						$tmp_email = stripslashes_deep( $a->email );
						if ( isset( $rsvp_pro_saved_form_vars['attending' . $a->id . 'Email'] ) ) {
							$tmp_email = $rsvp_pro_saved_form_vars['attending' . $a->id . 'Email'];
						}

						$form .= RSVP_PRO_START_PARA . rsvp_pro_beginning_form_field( '', '' ) .
								'<label for="attending' . $a->id . 'Email">' . $label . '</label>' .
								'<input type="text" name="attending' . $a->id . 'Email" id="attending' . $a->id . 'Email" value="' . htmlspecialchars( $tmp_email ) . '" ' .
								( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_REQUIRED ) === 'Y' ) ? 'required  data-rule-email="true"' : '' ) . ' 
                         class="rsvpEmailField" data-rule-rsvpProEmailUnique="true" data-msg-required="' . esc_attr( $js_validation ) . '" />' .
								RSVP_PRO_END_FORM_FIELD . RSVP_PRO_END_PARA;
					}
				} else {
					$form .= rsvp_pro_beginning_form_field( '', '' ) . RSVP_PRO_START_PARA .
							sprintf(
								rsvp_pro_get_frontend_string( 'associated_events_label' ),
								htmlspecialchars( $a->firstName . ' ' . $a->lastName )
							) .
							RSVP_PRO_END_PARA;
				}// if(does_user_have_access_to_event($rsvp_id, $a->id)):
				$form .= rsvp_pro_build_sub_event_main_form( $a->id, $a->id . 'Existing', $rsvp_form_js_ids, false );
				$form .= rsvp_pro_buildAdditionalQuestions( $a->id, $a->id, false, $rsvp_form_js_ids );
				$form .= "</div>\r\n"; // -- rsvpAdditionalAttendeeQuestions
				$form .= "</div>\r\n";
			} // if($a->id != ...)
		} // foreach($associations...)
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_ADDITIONAL ) !== 'Y' ) {
		$available_guest_count = $num_guests - count( $new_rsvps );

		if ( $available_guest_count < 0 ) {
			$available_guest_count = 0;
		}

		if ( $available_guest_count > 0 ) {
			$text = sprintf( rsvp_pro_get_frontend_string( 'invite_message' ), $available_guest_count );

			$additional_verbiage_text = trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ADD_ADDITIONAL_VERBIAGE ) );
			if ( '' !== $additional_verbiage_text ) {
				if ( ( strpos( $additional_verbiage_text, '%d' ) !== false ) || ( strpos( $additional_verbiage_text, '%s' ) !== false ) ) {
					$text = sprintf( $additional_verbiage_text, $available_guest_count );
				} else {
					$text = $additional_verbiage_text;
				}
			}

			$button_text = rsvp_pro_get_frontend_string( 'add_additional_guests' );
			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ADD_ATTENDEE_BUTTON_TEXT ) !== '' ) {
				$button_text = stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ADD_ATTENDEE_BUTTON_TEXT ) );
			}

			$form .= "<div id=\"additionalRsvpContainer_" . $rsvp_id . "\">\r\n
				<h3>$text</h3>\r\n
			<input type=\"hidden\" name=\"additionalRsvp\" id=\"additionalProRsvp_" . $rsvp_id . "\" value=\"" . count( $new_rsvps ) . "\" />
            <input type=\"hidden\" name=\"additionalRsvpIds\" id=\"additionalRsvpIds_" . $rsvp_id ."\" value=\"\" />
			<div style=\"text-align:right\" id=\"addProRsvp\" class=\"addAdditionalProAttendees\"><button class=\"rsvpButton\">$button_text</button></div></div>";
		}
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_GDPR_QUESTION ) ) {
		$gdpr_text = rsvp_pro_get_frontend_string( 'gdpr_question' );
		if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_QUESTION_TEXT ) ) {
			$gdpr_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_QUESTION_TEXT );
		}

		$gdpr_required = 'This field is required';
		if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_JS_MESSAGE ) ) {
			$gdpr_required = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_JS_MESSAGE );
		}
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpBorderTop' ) . '<div>' .
				'<input type="checkbox" name="gdpr_question" id="gdpr_question" value="Y" required data-msg-required="' . esc_attr( $gdpr_required ) . '" /> ' .
				'<label for="gdpr_question">' . $gdpr_text . '</label></div>' .
				RSVP_PRO_END_FORM_FIELD;
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_RECAPTCHA ) ) {
		if ( isset( $rsvp_pro_saved_form_vars['captcha_validation_message'] ) ) {
			$form .= '<p class="rsvpParagraph">' . esc_html( $rsvp_pro_saved_form_vars['captcha_validation_message'] ) . '</p>';
		}
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpCaptchaContainer' ) .
				'<div class="g-recaptcha" data-sitekey="' . esc_attr( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RECAPTCHA_SITE_KEY ) ) . '" id="rsvpCaptcha"></div>' .
				RSVP_PRO_END_FORM_FIELD;
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_TURNSTILE ) ) {
		if ( isset( $rsvp_pro_saved_form_vars['captcha_validation_message'] ) ) {
			$form .= '<p class="rsvpParagraph">' . esc_html( $rsvp_pro_saved_form_vars['captcha_validation_message'] ) . '</p>';
		}
		$form .= rsvp_pro_beginning_form_field( '', 'rsvpCaptchaContainer' ) .
				'<div class="rsvp-pro-turnstile" data-sitekey="' . esc_attr( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_TURNSTILE_SITE_KEY ) ) . '" id="rsvpTurnstile"></div>' .
				RSVP_PRO_END_FORM_FIELD;
	}

	$form .= rsvp_pro_display_price_container( $rsvp_id );

	$button_text = rsvp_pro_get_frontend_string( 'rsvp_button_label' );
	if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_BUTTON_TEXT ) ) !== '' ) {
		$button_text = stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_BUTTON_TEXT ) );
	}
	$form        .= '<p class="rsvpParagraph rsvpSubmitContainer">' . "<input type=\"submit\" value=\"$button_text\" class=\"rsvpSubmit\" />" . RSVP_PRO_END_PARA;
	$simple_nonce = WPSimpleNonce::createNonce( 'rsvp_fe_form' );
	$form        .= '  <input type="hidden" name="rsvp_nonce_name" value="' . $simple_nonce['name'] . '" />';
	$form        .= '  <input type="hidden" name="rsvp_nonce_value" value="' . $simple_nonce['value'] . '" />';
	$form        .= "</form>\r\n";
	$form        .= rsvp_pro_display_modify_registration_link( $attendee_id );

	$js = rsvp_pro_output_additional_js( $rsvp_id, $attendee, $attendee_id );

	return $js . $form;
}

/**
 * Outputs the price container and related text.
 *
 * @param  int $event_id The current event ID we want to display the price container for.
 * @return string        The container to display the price information.
 */
function rsvp_pro_display_price_container( $event_id ) {
	$output = '';

	if ( 'Y' === rsvp_pro_get_event_option( $event_id, RSVP_PRO_OPTION_ENABLE_PAYMENTS ) ) {
		// TODO: Change the ticket total label text so it can be customized with an option.
		$output  = '<div id="rsvpProTicketPriceContainer">';
		$output .= '<p class="rsvpParagraph">' . rsvp_pro_get_frontend_string( 'ticket_total_label' ) . ' <span id="rsvpProTicketTotal"></span>.</p>';
		$output .= '</div>';
	}

	return $output;
}

/**
 * Displays the modify registration link if the show new attendee form option is enabled and
 * the current attendee is a new attendee.
 *
 * @param  int $attendee_id The attendee ID of the current person RSVP'ing.
 *
 * @return string              The output of the link or an empty string if no link should be displayed.
 */
function rsvp_pro_display_modify_registration_link( $attendee_id ) {
	global $rsvp_id;

	$output = '';

	if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_NEW_ATTENDEE_FORM_FIRST ) === 'Y' ) && ( $attendee_id <= 0 ) ) {
		$link_text = rsvp_pro_get_frontend_string( 'modify_registration_link_text' );
		if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIND_ATTENDEES_LINK_TEXT ) ) {
			$link_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIND_ATTENDEES_LINK_TEXT );
		}

		$output .= '<div class="rsvpFindAttendeeLinkContainer">';
		$output .= '<p class="rsvpParagraph"><a href="?rsvpStep' . $rsvp_id . '=attendee_search">' . $link_text . '</a></p>';
		$output .= '</div>';
	}

	return $output;
}

/**
 * Creates the HTML for sub-events for a given event.
 *
 * @param  int    $attendee_id The attendee ID for the main RSVP.
 * @param  string $base_name The base name for the HTML form elements.
 *
 * @return string             The HTML form output for sub-events.
 */
function rsvp_pro_build_sub_event_main_form( $attendee_id, $base_name, &$rsvp_form_js_ids, $main_attendee = true ) {
	global $wpdb, $rsvp_id;
	global $rsvp_pro_saved_form_vars;

	$output = '';
	$sql    = 'SELECT eventName, e.id, se.rsvpStatus
	FROM ' . PRO_EVENT_TABLE . ' e
	LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpEventID = e.id AND se.rsvpAttendeeID = %d
	WHERE parentEventID = %d ORDER BY e.id';

	$sub_events = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $rsvp_id ) );
	if ( count( $sub_events ) > 0 ) {
		foreach ( $sub_events as $se ) {
			if ( does_user_have_access_to_event( $se->id, $attendee_id ) ) :
				$rsvp_for_label = rsvp_pro_get_frontend_string( 'rsvp_for_label' );
				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MULTI_EVENT_TITLE ) != '' ) {
					$rsvp_for_label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MULTI_EVENT_TITLE );
				}
				$output .= '<h4 class="rsvpSubEventTitle">' . sprintf( $rsvp_for_label, esc_html( stripslashes( $se->eventName ) ) ) . '</h4>';

				if ( rsvp_pro_get_event_option( $se->id, RSVP_PRO_OPTION_SHOW_EVENT_INFO_ON_FRONTEND ) === 'Y' ) {
					$output .= "<div id=\"rsvpProEventDescription\">\r\n";
					$output .= RSVP_PRO_START_PARA . rsvp_pro_get_event_information( $se->id, RSVP_PRO_INFO_DESCRIPTION ) . RSVP_PRO_END_PARA;
					$output .= "</div>\r\n";
				}

				$yes_text                                = rsvp_pro_get_frontend_string( 'yes_text' );
				$no_text                                 = rsvp_pro_get_frontend_string( 'no_text' );
				$waitlist_text                           = rsvp_pro_get_frontend_string( 'waitlist_text' );
				$rsvp_js_id                              = uniqid();
				$rsvp_form_js_ids[ 'RsvpSub' . $se->id ] = $rsvp_js_id;

				$yes_sub_verbiage = ( ( trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_YES_VERBIAGE ) ) !== '' ) ? rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_YES_VERBIAGE ) :
					sprintf( rsvp_pro_get_frontend_string( 'rsvp_sub_event_yes_label' ), stripslashes( $se->eventName ) ) );

				$no_sub_verbiage   = ( ( trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_NO_VERBIAGE ) ) !== '' ) ? rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_NO_VERBIAGE ) :
					sprintf( rsvp_pro_get_frontend_string( 'rsvp_sub_event_no_label' ), stripslashes( $se->eventName ) ) );
				$waitlist_verbiage = sprintf( rsvp_pro_get_frontend_string( 'rsvp_sub_event_waitlist_label' ), stripslashes( $se->eventName ) );
				if ( trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_WAITLIST_VERBIAGE ) ) !== '' ) {
					$waitlist_verbiage = sprintf( trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_WAITLIST_VERBIAGE ) ), $se->eventName );
				}

				$maybe_verbiage = rsvp_pro_get_frontend_string( 'rsvp_sub_event_maybe_label' );
				if ( trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_MAYBE_VERBIAGE ) ) !== '' ) {
					$maybe_verbiage = trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_MAYBE_VERBIAGE ) );
				}

				$plus_one_verbiage = rsvp_pro_get_frontend_string( 'plus_one_label' );
				if ( trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_PLUS_ONE_LABEL ) ) !== '' ) {
					$plus_one_verbiage = trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_PLUS_ONE_LABEL ) );
				}

				if ( ! $main_attendee ) {
					$yes_sub_verbiage  = apply_filters( 'rsvp_yes_associated', $yes_sub_verbiage, null, $se->id );
					$no_sub_verbiage   = apply_filters( 'rsvp_no_associated', $no_sub_verbiage, null, $se->id );
					$waitlist_verbiage = apply_filters( 'rsvp_waitlist_associated', $waitlist_verbiage, null, $se->id );
					$maybe_verbiage    = apply_filters( 'rsvp_maybe_associated', $maybe_verbiage, null, $se->id );
				}

				$required_rsvp = '';
				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_RSVP_REQUIRED ) === 'Y' ) {
					$required_rsvp = ' required';
				}

				if ( rsvp_pro_frontend_max_limit_hit( $se->id ) ) {
					$output        .= rsvp_pro_handle_max_limit_reached_message( $se->id );
					$otuput        .= rsvp_pro_handle_waitlist_message( $se->id );
					$required_rsvp .= ' disabled="true"';
				}

				$user_rsvp_status = 'NoResponse';
				if ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_DEFAULT_RSVP_VALUE ) !== '' ) {
					$user_rsvp_status = rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_DEFAULT_RSVP_VALUE );
					$user_rsvp_status = ucfirst( $user_rsvp_status );
				}

				if ( isset( $rsvp_pro_saved_form_vars[ $base_name . 'RsvpSub' . $se->id ] ) ) {
					$user_rsvp_status = rsvp_pro_translate_form_value_to_status( $rsvp_pro_saved_form_vars[ $base_name . 'RsvpSub' . $se->id ] );
				} elseif ( isset( $se ) && ( strtolower( $se->rsvpStatus ) !== 'noresponse' ) && ! empty( $se->rsvpStatus ) ) {
					$user_rsvp_status = $se->rsvpStatus;
				} elseif ( isset( $_REQUEST['rsvpStatus'] ) && rsvp_pro_is_allowed_status( $_REQUEST['rsvpStatus'] ) ) {
					$user_rsvp_status = $_REQUEST['rsvpStatus'];
				}

				if ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_RSVP_HIDE ) === 'Y' ) {
					$output .= '<input type="hidden" name="' . $base_name . 'RsvpSub' . $se->id . '" value="' . rsvp_pro_translate_status_to_form_value( $user_rsvp_status ) . '" />';
				} else {
					if ( trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_QUESTION ) ) !== '' ) {
						$output .= RSVP_PRO_START_PARA . trim( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_QUESTION ) ) . RSVP_PRO_END_PARA;
					}

					$output .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
							   '<input type="radio" name="' . $base_name . 'RsvpSub' . $se->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="Y" id="' . $base_name . 'RsvpSub' . $se->id . 'Y" ' . ( ( $user_rsvp_status === 'Yes' ) ? 'checked="checked"' : '' ) . " $required_rsvp class=\"rsvpStatusInput\" /> <label for=\"" . $base_name . 'RsvpSub' . $se->id . 'Y">' . $yes_sub_verbiage . '</label>' .
							   RSVP_PRO_END_FORM_FIELD;

					if ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_ENABLE_MAYBE ) === 'Y' ) {
						$output .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
								   '<input type="radio" name="' . $base_name . 'RsvpSub' . $se->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="M" id="' . $base_name . 'RsvpSub' . $se->id . 'M" ' . ( ( $user_rsvp_status === 'Maybe' ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
								   '<label for="' . $base_name . 'RsvpSub' . $se->id . 'M">' . $maybe_verbiage . '</label>' .
								   RSVP_PRO_END_FORM_FIELD;
					}

					$output .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
							   '<input type="radio" name="' . $base_name . 'RsvpSub' . $se->id . '"  data-rsvp-js-id="' . $rsvp_js_id . '" value="N" id="' . $base_name . 'RsvpSub' . $se->id . 'N" ' . ( ( $user_rsvp_status === 'No' ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
							   '<label for="' . $base_name . 'RsvpSub' . $se->id . 'N">' . $no_sub_verbiage . '</label>' .
							   RSVP_PRO_END_FORM_FIELD;

					if ( ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) === 'Y' ) && rsvp_pro_frontend_max_limit_hit( $se->id ) ) {
						$output .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
								   '<input type="radio" name="' . $base_name . 'RsvpSub' . $se->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="W" id="' . $base_name . 'RsvpSub' . $se->id . 'W" ' . ( ( $user_rsvp_status === 'Waitlist' ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
								   '<label for="' . $base_name . 'RsvpSub' . $se->id . 'W">' . $waitlist_verbiage . '</label>' .
								   RSVP_PRO_END_FORM_FIELD;
					}

					if ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_PLUS_ONE_ENABLED ) === 'Y' && $main_attendee ) {
						$output .= rsvp_pro_beginning_form_field( '', 'rsvpRsvpQuestionArea' ) .
								   '<input type="radio" name="' . $base_name . 'RsvpSub' . $se->id . '" data-rsvp-js-id="' . $rsvp_js_id . '" value="PlusOne" id="' . $base_name . 'RsvpSub' . $se->id . 'PlusOne" ' . ( ( $user_rsvp_status === 'PlusOne' ) ? 'checked="checked"' : '' ) . ' class="rsvpStatusInput" /> ' .
								   '<label for="' . $base_name . 'RsvpSub' . $se->id . 'PlusOne">' . $plus_one_verbiage . '</label>' .
								   RSVP_PRO_END_FORM_FIELD;
					}
				}
			endif; // if(does_user_have_access_to_event($se->id, $attendee_id)):
		} // foreach($sub_events as $se) {
	}

	return $output;
}

/**
 * Retrieves the previous attendee's answer to a question.
 *
 * @param  int $attendee_id The attendee we want the answer for.
 * @param  int $question_id The question we want the answer for.
 *
 * @return mixed              The attendee's answer.
 */
function rsvp_pro_revtrieve_previous_answer( $attendee_id, $question_id ) {
	global $wpdb;
	$answers = '';
	if ( ( $attendee_id > 0 ) && ( $question_id > 0 ) ) {
		$rs = $wpdb->get_results( $wpdb->prepare( 'SELECT answer FROM ' . PRO_ATTENDEE_ANSWERS . ' WHERE questionID = %d AND attendeeID = %d', $question_id, $attendee_id ) );
		if ( count( $rs ) > 0 ) {
			$answers = stripslashes( $rs[0]->answer );
		}
	}

	return $answers;
}

/**
 * Creates the question inputs.
 *
 * @param  int    $attendee_id The attendee we want the question inputs for.
 * @param  string $prefix The prefix for the custom questions.
 * @param  object $questions The questions we need to generate.
 * @param  array  $rsvp_form_js_ids The ids we need to use tie the RSVP question to the custom questions
 *
 * @return string              The custom question inputs.
 */
function rsvp_pro_create_question_inputs( $attendee_id, $prefix, $questions, $rsvp_form_js_ids ) {
	global $wpdb;
	global $rsvp_id;
	global $rsvp_pro_saved_form_vars;

	$output   = '';
	$attendee = new Rsvp_Pro_Attendee( $attendee_id );
	if ( count( $questions ) > 0 ) {
		foreach ( $questions as $q ) {
			if ( does_user_have_access_to_event( $q->rsvpEventID, $attendee_id ) ) :
				$old_answer = rsvp_pro_revtrieve_previous_answer( $attendee_id, $q->id );
				if ( isset( $rsvp_pro_saved_form_vars[$prefix . 'question' . $q->id] ) ) {
					$old_answer = $rsvp_pro_saved_form_vars[$prefix . 'question' . $q->id];

					if ( is_array( $old_answer ) ) {
						// We need to loop through and get the actual answers...
						$tmp_old_answer = array();
						$sql             = 'SELECT answer FROM ' . PRO_QUESTION_ANSWERS_TABLE . ' WHERE id IN ( ' . esc_sql( implode( ',', $old_answer ) ) . ')';
						$tmp_ans         = $wpdb->get_results( $sql );
						foreach($tmp_ans as $ans ) {
							$tmp_old_answer[] = stripslashes_deep( $ans->answer );
						}
						$old_answer = implode( '||', $tmp_old_answer );
					}
				}

				$custom_attributes                 = array();
				$custom_attributes['data-rsvp-id'] = $q->rsvpEventID;
				if ( $q->rsvpEventID === $rsvp_id ) {
					$custom_attributes['data-rsvp-main-event'] = 'Y';

					if ( isset( $rsvp_form_js_ids['main'] ) ) {
						$custom_attributes['data-rsvp-question-js-id'] = $rsvp_form_js_ids['main'];
					}
				} else {
					$custom_attributes['data-rsvp-main-event'] = 'N';

					if ( isset( $rsvp_form_js_ids[ 'RsvpSub' . $q->rsvpEventID ] ) ) {
						$custom_attributes['data-rsvp-question-js-id'] = $rsvp_form_js_ids[ 'RsvpSub' . $q->rsvpEventID ];
					}
				}

				if ( ! empty( $q->only_show_on_status ) ) {
					$custom_attributes['data-rsvp-only-show-on'] = stripslashes_deep( $q->only_show_on_status );
				}

				$css_classes = 'rsvpCustomQuestion';
				if ( QT_PRO_MULTI === $q->questionType ) {
					$css_classes .= ' rsvpCustomQuestionMultipleChoice';
				} elseif ( QT_PRO_DROP === $q->questionType ) {
					$css_classes .= ' rsvpCustomQuestionDropdown';
				} elseif ( QT_PRO_LONG === $q->questionType ) {
					$css_classes .= ' rsvpCustomQuestionLongAnswer';
				} elseif ( QT_PRO_RADIO === $q->questionType ) {
					$css_classes .= ' rsvpCustomQuestionRadio';
				} elseif ( QT_PRO_READ_ONLY === $q->questionType ) {
					$css_classes .= ' rsvpCustomQuestionReadonly';
				} elseif ( QT_DATEPICKER === $q->questionType ) {
					$css_classes .= ' rsvpCustomQuestionDatepicker';
				} else {
					$css_classes .= ' rsvpCustomQuestionShortAnswer';
				}

				$question_text = stripslashes( $q->question );
				$key_name      = stripslashes( rsvp_pro_get_event_name( $q->rsvpEventID ) . ' - ' . $question_text );
				$question_text = rsvp_pro_get_dynamic_translated_string( $key_name, $question_text, $q->rsvpEventID );
				$output       .= rsvp_pro_beginning_form_field( $prefix . 'rsvpCustomQuestion' . $q->id, $css_classes, $custom_attributes ) .
								  '<div class="rsvpCustomQuestionQuestionContainer">' . $question_text . '</div>';

				if ( QT_PRO_MULTI === $q->questionType ) {
					$old_answers = explode( '||', $old_answer );

					$answers = $wpdb->get_results( $wpdb->prepare( 'SELECT id, answer, defaultAnswer FROM ' . PRO_QUESTION_ANSWERS_TABLE . ' WHERE questionID = %d', $q->id ) );
					if ( count( $answers ) > 0 ) {
						$i = 0;
						foreach ( $answers as $a ) {
							$required_attribute      = '';
							$required_text_attribute = '';
							if ( ( $i == 0 ) && ( $q->required == 'Y' ) ) {
								$required_attribute = 'data-rule-rsvpRequired="true"';
							}

							if ( ( $i == 0 ) && ( $q->required_text !== '' ) ) {
								$required_text_attribute = 'data-msg-rsvpRequired="' . esc_attr( stripslashes( $q->required_text ) ) . '"';
							}

							if ( empty( $old_answer ) && ( $a->defaultAnswer == 'Y' ) ) {
								$old_answers = array( $a->id );
							}

							$answer_text = stripslashes( $a->answer );
							$key_name    = stripslashes( $q->question . ' - ' . $a->answer );
							$answer_text = rsvp_pro_get_dynamic_translated_string( $key_name, $answer_text, $q->rsvpEventID );

							$output .= rsvp_pro_beginning_form_field( '', 'rsvpCheckboxCustomQ' ) . '<input type="checkbox" name="' . $prefix . 'question' . $q->id . '[]" id="' . $prefix . 'question' . $q->id . $a->id . '" value="' . $a->id . '" '
									   . ( ( in_array( stripslashes( $a->answer ), $old_answers ) ) ? ' checked="checked"' : '' ) . " $required_attribute $required_text_attribute data-rsvpprefix=\"$prefix\" />" .
									   '<label for="' . $prefix . 'question' . $q->id . $a->id . '">' . $answer_text . "</label>\r\n" . RSVP_PRO_END_FORM_FIELD;
							++ $i;
						}

						if ( 'Y' === $q->other_question ) {
							$answer_text  = rsvp_pro_get_frontend_string( 'custom_question_other_label' );
							$answer       = '';
							$answer_found = false;

							foreach( $old_answers as $oa ) {
								if ( stripos( $oa, 'other--') !== false ) {
									$answer_found = true;
									$answer       = str_ireplace( 'other--', '', $oa );
								}
							}

							if ( '' !== $q->other_question_text ) {
								$answer_text = stripslashes_deep( $q->other_question_text );
							}

							$output .= rsvp_pro_beginning_form_field( '', 'rsvpCheckboxCustomQ' ) . '<input type="checkbox" name="' . $prefix . 'question' . $q->id . '[]" id="' . $prefix . 'question' . $q->id . 'other" value="other" '
									   . ( ( $answer_found ) ? ' checked="checked"' : '' ) . " $required_attribute $required_text_attribute data-rsvpprefix=\"$prefix\" />" .
									   '<label for="' . $prefix . 'question' . $q->id . 'other">' . $answer_text . "</label>\r\n" . 
									   '<input type="text" name="'. $prefix . 'question' . $q->id . 'other" value="' . esc_attr( $answer ) . '" />' .
									   RSVP_PRO_END_FORM_FIELD;
						}

						$output .= "<div class=\"rsvpClear\">&nbsp;</div>\r\n";
					}
				} elseif ( QT_PRO_DROP === $q->questionType ) {
					$required_text_attribute = '';
					if ( $q->required_text !== '' ) {
						$required_text_attribute = 'data-msg-rsvpRequired="' . esc_attr( stripslashes( $q->required_text ) ) . '"';
					}

					$output .= '<select name="' . $prefix . 'question' . $q->id . '" size="1" ' . ( ( $q->required === 'Y' ) ? 'data-rule-rsvpRequired="true"' : '' ) . " $required_text_attribute data-rsvpprefix=\"$prefix\">\r\n" .
								"<option value=\"\">--</option>\r\n";
					$answers = $wpdb->get_results( $wpdb->prepare( 'SELECT id, answer, defaultAnswer FROM ' . PRO_QUESTION_ANSWERS_TABLE . ' WHERE questionID = %d', $q->id ) );
					if ( count( $answers ) > 0 ) {
						foreach ( $answers as $a ) {
							if ( empty( $old_answer ) && ( $a->defaultAnswer === 'Y' ) ) {
								$old_answer = $a->answer;
							}

							$answer_text = stripslashes( $a->answer );
							$key_name    = stripslashes( $q->question . ' - ' . $a->answer );
							$answer_text = rsvp_pro_get_dynamic_translated_string( $key_name, $answer_text, $q->rsvpEventID );

							$output .= '<option value="' . $a->id . '" ' . ( ( stripslashes( $a->answer ) === $old_answer ) ? ' selected="selected"' : '' ) . '>' . $answer_text . "</option>\r\n";
						}
					}
					$output .= "</select>\r\n";
				} elseif ( QT_PRO_LONG === $q->questionType ) {
					$required_text_attribute = '';
					if ( $q->required_text !== '' ) {
						$required_text_attribute = 'data-msg-rsvpRequired="' . esc_attr( stripslashes( $q->required_text ) ) . '"';
					}

					$output .= '<textarea name="' . $prefix . 'question' . $q->id . '" rows="5" cols="35" ' . ( ( $q->required === 'Y' ) ? 'data-rule-rsvpRequired="true"' : '' ) . " $required_text_attribute data-rsvpprefix=\"$prefix\">" . esc_html( $old_answer ) . '</textarea>';
				} elseif ( QT_PRO_RADIO === $q->questionType ) {
					$answers = $wpdb->get_results( $wpdb->prepare( 'SELECT id, answer, defaultAnswer FROM ' . PRO_QUESTION_ANSWERS_TABLE . ' WHERE questionID = %d', $q->id ) );
					if ( count( $answers ) > 0 ) {
						$i = 0;
						foreach ( $answers as $a ) {
							$required_attribute      = '';
							$required_text_attribute = '';
							if ( ( $i === 0 ) && ( $q->required === 'Y' ) ) {
								$required_attribute = 'data-rule-rsvpRequired="true"';
							}

							if ( ( $i === 0 ) && ( $q->required_text !== '' ) ) {
								$required_text_attribute = 'data-msg-rsvpRequired="' . esc_attr( stripslashes( $q->required_text ) ) . '"';
							}

							if ( empty( $old_answer ) && ( $a->defaultAnswer === 'Y' ) ) {
								$old_answer = $a->answer;
							}

							$answer_text = stripslashes( $a->answer );
							$key_name    = stripslashes( $q->question . ' - ' . $a->answer );
							$answer_text = rsvp_pro_get_dynamic_translated_string( $key_name, $answer_text, $q->rsvpEventID );

							$output .= rsvp_pro_beginning_form_field( '', 'rsvpRadioCustomQ' ) . '<input type="radio" name="' . $prefix . 'question' . $q->id . '" id="' . $prefix . 'question' . $q->id . $a->id . '" value="' . $a->id . '" '
									   . ( ( stripslashes( $a->answer ) === $old_answer ) ? ' checked="checked"' : '' ) . " $required_attribute $required_text_attribute data-rsvpprefix=\"$prefix\" /> " .
									   '<label for="' . $prefix . 'question' . $q->id . $a->id . '">' . $answer_text . "</label>\r\n" . RSVP_PRO_END_FORM_FIELD;
							++ $i;
						}

						if ( 'Y' === $q->other_question ) {
							$answer_text  = rsvp_pro_get_frontend_string( 'custom_question_other_label' );
							$answer       = '';
							$answer_found = false;

							if ( stripos( $old_answer, 'other--') !== false ) {
								$answer_found = true;
								$answer       = str_ireplace( 'other--', '', $old_answer );
							}

							if ( '' !== $q->other_question_text ) {
								$answer_text = stripslashes_deep( $q->other_question_text );
							}

							$output .= rsvp_pro_beginning_form_field( '', 'rsvpCheckboxCustomQ' ) . '<input type="radio" name="' . $prefix . 'question' . $q->id . '" id="' . $prefix . 'question' . $q->id . 'other" value="other" '
									   . ( ( $answer_found ) ? ' checked="checked"' : '' ) . " $required_attribute $required_text_attribute data-rsvpprefix=\"$prefix\" />" .
									   '<label for="' . $prefix . 'question' . $q->id . 'other">' . $answer_text . "</label>\r\n" . 
									   '<input type="text" name="'. $prefix . 'question' . $q->id . 'other" value="' . esc_attr( $answer ) . '" />' .
									   RSVP_PRO_END_FORM_FIELD;
						}						
						$output .= "<div class=\"rsvpClear\">&nbsp;</div>\r\n";
					}
				} elseif ( QT_PRO_READ_ONLY === $q->questionType ) {
					$output .= '<div class="rsvpCustomQuestionReadonlyAnswer">' . esc_html( $old_answer ) . '</div>';
				} elseif ( QT_PRO_FILE === $q->questionType ) {
					$output .= '<div class="rsvpCustomQuestionFileAnswer">';
					$output .= '<input type="file" name="' . $prefix . 'question' . $q->id . '" />' . "\r\n";
					if ( isset( $old_answer ) && ( 0 < $old_answer ) && ( false !== wp_get_attachment_url( $old_answer ) ) ) {
						$file_url = wp_get_attachment_url( $old_answer );
						$output .= '<div class="file_attachment_container">
							<a href="' . esc_attr( $file_url ) . '">' . rsvp_pro_get_admin_string( 'admin_attendee_view_file' ) . '</a> | 
							<a href="#" class="delete_attendee_attachment" data-attendee-token="' . $attendee->get_token() . '" data-question-id="' . $q->id . '">' . rsvp_pro_get_admin_string( 'admin_attendee_delete_file' ) . '</a>
						</div>';
					}
					$output .= '</div>';
				} elseif ( QT_NUMERIC === $q->questionType ) {
					$required_text_attribute = '';
					if ( '' !== $q->required_text ) {
						$required_text_attribute = 'data-msg-rsvpRequired="' . esc_attr( stripslashes( $q->required_text ) ) . '"';
					}

					$output .= '<input type="text" name="' . $prefix .
						'question' . $q->id . '" value="' . esc_attr( $old_answer ) . '"' .
						' size="25" data-rule-digits="true" ' . ( ( 'Y' === $q->required ) ? 'data-rule-rsvpRequired="true"' : '' ) .
						' ' . $required_text_attribute . 'data-rsvpprefix="' . $prefix . '" class="rsvpProCustomQuestionNumeric" />';
				} elseif ( QT_DATEPICKER === $q->questionType ) {
					$required_text_attribute = '';
					if ( $q->required_text !== '' ) {
						$required_text_attribute = 'data-msg-rsvpRequired="' . esc_attr( stripslashes( $q->required_text ) ) . '"';
					}

					$output .= '<input type="text" name="' . $prefix .
							'question' . $q->id . '" value="' . htmlspecialchars( $old_answer ) .
							'" size="25" ' . ( ( $q->required === 'Y' ) ? 'data-rule-rsvpRequired="true"' : '' ) .
							" $required_text_attribute data-rsvpprefix=\"$prefix\" class=\"rsvpProCustomQuestionDatePicker\" />";
				} else {
					// normal text input.
					$required_text_attribute = '';
					if ( $q->required_text !== '' ) {
						$required_text_attribute = 'data-msg-rsvpRequired="' . esc_attr( stripslashes( $q->required_text ) ) . '"';
					}

					$output .= '<input type="text" name="' . $prefix . 'question' . $q->id . '" value="' . htmlspecialchars( $old_answer ) . '" size="25" ' . ( ( $q->required === 'Y' ) ? 'data-rule-rsvpRequired="true"' : '' ) . " $required_text_attribute data-rsvpprefix=\"$prefix\" />";
				}

				$output .= RSVP_PRO_END_FORM_FIELD;
			endif;
		}
	}

	return $output;
}

function rsvp_pro_buildAdditionalQuestions( $attendee_id, $prefix, $main_attendee, $rsvp_form_js_ids, $show_hidden = false ) {
	global $wpdb, $rsvp_pro_saved_form_vars;
	global $rsvp_id;

	$output = '<div class="rsvpCustomQuestions">';

	$hidden_question_type = '';

	if ( ! $show_hidden ) {
		$hidden_question_type = " AND qt.questionType <> 'hidden' ";
	}

	$sql      = 'SELECT q.id, q.question, questionType, q.sortOrder, q.required, q.required_text, 
		e.id AS rsvpEventID, q.only_show_on_status, q.other_question, q.other_question_text  
	FROM ' . PRO_QUESTIONS_TABLE . ' q 
	INNER JOIN ' . PRO_QUESTION_TYPE_TABLE . ' qt ON qt.id = q.questionTypeID
	INNER JOIN ' . PRO_EVENT_TABLE . " e ON e.id = q.rsvpEventID
	WHERE (q.permissionLevel = 'public'
		OR (q.permissionLevel = 'private' AND q.id IN (SELECT questionID FROM " . PRO_QUESTION_ATTENDEES_TABLE . " WHERE attendeeID = $attendee_id))
		OR (q.permissionLevel = 'private' AND ( q.ask_only_associated = 'Y' ) AND (0 = $attendee_id)) )
	AND q.rsvpEventID = $rsvp_id  $hidden_question_type ";
	$unionSql = ' UNION SELECT q.id, q.question, questionType, q.sortOrder, q.required, q.required_text, e.id AS rsvpEventID, q.only_show_on_status, q.other_question, q.other_question_text FROM ' . PRO_QUESTIONS_TABLE . ' q
	INNER JOIN ' . PRO_QUESTION_TYPE_TABLE . ' qt ON qt.id = q.questionTypeID
	INNER JOIN ' . PRO_EVENT_TABLE . " e ON e.id = q.rsvpEventID
	WHERE e.parentEventID = $rsvp_id AND
	(q.permissionLevel = 'public'
		OR (q.permissionLevel = 'private' AND q.id IN (SELECT questionID FROM " . PRO_QUESTION_ATTENDEES_TABLE . " WHERE attendeeID = $attendee_id)) 
		OR (q.permissionLevel = 'private' AND ( q.ask_only_associated = 'Y' ) AND (0 = $attendee_id)) )  $hidden_question_type  ";
	if ( ! $main_attendee ) {
		$sql      .= "  AND `grouping` <> '" . RSVP_PRO_QG_MULTI . "' ";
		$unionSql .= "  AND `grouping` <> '" . RSVP_PRO_QG_MULTI . "' ";
	}

	if ( $main_attendee ) {
		$sql      .= " AND q.ask_only_associated <> 'Y' ";
		$unionSql .= " AND q.ask_only_associated <> 'Y' ";
	}
	$unionSql .= ' ORDER BY sortOrder';

	$questions = $wpdb->get_results( $sql . $unionSql );
	$output   .= rsvp_pro_create_question_inputs( $attendee_id, $prefix, $questions, $rsvp_form_js_ids );

	return $output . '</div>';
}

/**
 * Attempts to find the attendee for this event.
 *
 * @param  string &$output The otuput of text that we want to display to the user.
 * @param  string &$text The original text that is on the page that we want to change based on our output.
 *
 * @return string          [description]
 */
function rsvp_pro_find( &$output, &$text ) {
	global $wpdb, $rsvp_first_name, $rsvp_last_name, $rsvp_passcode;
	global $rsvp_id, $rsvp_hide_new_form, $rsvp_hide_edit_form;

	$rsvp_form_action         = htmlspecialchars( rsvp_pro_getCurrentPageURL() );
	$passcodeOptionEnabled    = ( rsvp_pro_require_passcode( $rsvp_id ) ) ? true : false;
	$emailLookupEnabled       = ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ATTENDEE_LOOKUP_VIA_EMAIL ) == 'Y' ) ? true : false;
	$full_name_lookup_enabled = ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FULL_NAME_SEARCH ) ) ? true : false;
	$passcodeOnlyOption       = ( rsvp_pro_require_only_passcode_to_register( $rsvp_id ) ) ? true : false;
	$lastNameNotRequired      = ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_NOT_REQUIRED ) == 'Y' ) ? true : false;
	$hi_text                  = ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HI_TEXT ) != '' ) ? rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HI_TEXT ) : rsvp_pro_get_frontend_string( 'hi_text' );
	$rsvp_first_name          = isset( $_REQUEST['firstName'] ) ? $_REQUEST['firstName'] : '';
	$rsvp_last_name           = isset( $_REQUEST['lastName'] ) ? $_REQUEST['lastName'] : '';
	$rsvp_token               = isset( $_REQUEST['token'] ) ? $_REQUEST['token'] : '';
	$passcode                 = '';
	if ( isset( $_REQUEST['passcode'] ) ) {
		$passcode      = $_REQUEST['passcode'];
		$rsvp_passcode = $_REQUEST['passcode'];
	}

	$firstName = isset( $_REQUEST['firstName'] ) ? stripslashes( $_REQUEST['firstName'] ) : '';
	$lastName  = isset( $_REQUEST['lastName'] ) ? stripslashes( $_REQUEST['lastName'] ) : '';
	$firstName = trim( $firstName );
	$lastName  = trim( $lastName );
	$full_name = '';

	if ( $full_name_lookup_enabled && isset( $_REQUEST['full_name'] ) ) {
		$firstName = $_REQUEST['full_name'];
		$full_name = $_REQUEST['full_name'];
	} else {
		$full_name = $firstName . ' ' . $lastName;
	}

	if ( ! $passcodeOnlyOption && ! $emailLookupEnabled && ! $full_name_lookup_enabled && ( ( strlen( $firstName ) <= 1 ) || ( ! $lastNameNotRequired && ( strlen( $lastName ) <= 1 ) ) ) && empty( $rsvp_token ) ) {
		$output  = '<p class="rsvpParagraph" style="color:red">' . rsvp_pro_get_frontend_string( 'first_last_name_required' ) . "</p>\r\n";
		$output .= rsvp_pro_frontend_greeting();

		return rsvp_pro_handle_output( $text, $output );
	}

	$baseWhere = ' (SOUNDEX(firstName) = SOUNDEX(%s) OR (FIND_IN_SET(%s, nicknames) > 0)) AND SOUNDEX(lastName) = SOUNDEX(%s) ';

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PARTIAL_MATCH_USER_SEARCH ) == 'Y' ) {
		$baseWhere = " ( REPLACE(firstName, '\\\\\'', '') LIKE '%%%s%%' OR (FIND_IN_SET(%s, nicknames) > 0)) AND REPLACE(lastName, '\\\\\'', '') LIKE '%%%s%%' ";
		$baseWhere = " ( firstName LIKE '%%%s%%' OR (FIND_IN_SET(%s, nicknames) > 0)) AND lastName LIKE '%%%s%%' ";
		/*
		 This probably seems weird, but we need to triple encode otherwise when we get apostrophes in the
			the like it will not be found. Parsers can be a pain... */
		$firstName = $wpdb->esc_like( addslashes( $firstName ) );
		$lastName  = $wpdb->esc_like( addslashes( $lastName ) );
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DISABLE_USER_SEARCH ) == 'Y' ) {
		$baseWhere = ' (firstName = %s OR (FIND_IN_SET(%s, nicknames) > 0)) AND lastName = %s ';
	}

	if ( $lastNameNotRequired ) {
		$baseWhere = ' ( (firstName = %s OR (FIND_IN_SET(%s, nicknames) > 0)) AND ( lastName = %s OR 1=1 ) ) ';
	}

	if ( ! empty( $rsvp_token ) ) {
		$baseWhere = ' a.token = %s ';
	}

	// Try to find the user.
	if ( $passcodeOptionEnabled ) {
		if ( $passcodeOnlyOption ) {
			$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus,
                        (SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " 
                        WHERE rsvpStatus <> 'NoResponse' AND rsvpAttendeeID = a.id) AS subStatus, 
                        primaryAttendee, note, passcode, a.token
                    FROM " . PRO_ATTENDEES_TABLE . ' a
                    LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                    WHERE ';

			if ( ! empty( $rsvp_token ) ) {
				$sql .= ' token = %s ';
			} else {
				$sql .= ' ( passcode = %s OR alternate_passcode = %s) ';
			}

			$sql .= ' AND ( (a.rsvpEventID = %d) ';

			if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
				$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
			}

			$sql .= ') ORDER BY primaryAttendee DESC';

			if ( ! empty( $rsvp_token ) ) {
				$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $rsvp_token, $rsvp_id ) );
			} else {
				$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $passcode, $passcode, $rsvp_id ) );
			}
		} else {
			if ( $emailLookupEnabled ) {
				$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus, 
                        email, suffix, salutation ,
                           (SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " WHERE rsvpStatus <> 'NoResponse' AND rsvpAttendeeID = a.id) AS subStatus, primaryAttendee, note, passcode, a.token
						FROM " . PRO_ATTENDEES_TABLE . ' a
						LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                        WHERE email = %s AND ( passcode = %s OR alternate_passcode = %s ) AND ( (a.rsvpEventID = %d) ';

				if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
					$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
				}

				$sql .= ') ORDER BY primaryAttendee DESC';

				$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $_REQUEST['email'], $passcode, $passcode, $rsvp_id ) );
			} elseif ( $full_name_lookup_enabled ) {
				$baseWhere = ' SOUNDEX(CONCAT_WS(\' \', firstName, lastName)) = SOUNDEX(%s) ';
				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DISABLE_USER_SEARCH ) == 'Y' ) {
					$baseWhere = ' CONCAT_WS(\' \', firstName, lastName) = %s ';
				}
				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PARTIAL_MATCH_USER_SEARCH ) == 'Y' ) {
					$baseWhere = " CONCAT_WS(' ', firstName, lastName) LIKE '%%%s%%' ";
				}

				$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus, 
                        email, suffix, salutation ,
                           (SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " WHERE rsvpStatus <> 'NoResponse' AND rsvpAttendeeID = a.id) AS subStatus, primaryAttendee, note, passcode, a.token
						FROM " . PRO_ATTENDEES_TABLE . ' a
						LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                        WHERE ' . $baseWhere . ' AND ( passcode = %s OR alternate_passcode = %s ) AND ( (a.rsvpEventID = %d) ';

				

				if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
					$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
				}

				$sql .= ') ORDER BY primaryAttendee DESC';

				$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, trim($full_name), $passcode, $passcode, $rsvp_id ) );
			} else {
				$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus, 
                        email, suffix, salutation ,
                        (SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " WHERE rsvpStatus <> 'NoResponse' AND rsvpAttendeeID = a.id) AS subStatus, primaryAttendee, note, passcode, a.token
                        FROM " . PRO_ATTENDEES_TABLE . ' a
                        LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
						WHERE $baseWhere AND ( passcode = %s OR alternate_passcode = %s ) AND ( (a.rsvpEventID = %d) ";

				if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
					$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
				}

				$sql     .= ') ORDER BY primaryAttendee DESC';
				$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $firstName, $firstName, $lastName, $passcode, $passcode, $rsvp_id ) );
			}
		}
	} elseif ( $emailLookupEnabled ) {
		$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus, email, suffix, salutation ,
                    (SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " WHERE rsvpStatus <> 'NoResponse' AND rsvpAttendeeID = a.id) AS subStatus, primaryAttendee, note, passcode, a.token
                FROM " . PRO_ATTENDEES_TABLE . ' a
                LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                WHERE ';

		if ( ! empty( $rsvp_token ) ) {
			$sql .= ' token = %s ';
		} else {
			$sql .= ' email = %s ';
		}

		$sql .= ' AND ( (a.rsvpEventID = %d) ';
		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
		}

		$sql .= ') ORDER BY primaryAttendee DESC';

		if ( ! empty( $rsvp_token ) ) {
			$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $rsvp_token, $rsvp_id ) );
		} else {
			$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $_REQUEST['email'], $rsvp_id ) );	
		}
	} elseif ( $full_name_lookup_enabled ) {
		$baseWhere = ' SOUNDEX(CONCAT_WS(\' \', firstName, lastName)) = SOUNDEX(%s) ';
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DISABLE_USER_SEARCH ) == 'Y' ) {
			$baseWhere = ' CONCAT_WS(\' \', firstName, lastName) = %s ';
		}
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PARTIAL_MATCH_USER_SEARCH ) == 'Y' ) {
			$baseWhere = " CONCAT_WS(' ', firstName, lastName) LIKE '%%%s%%' ";
		}

		$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus, email, suffix, salutation ,
                    (SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " WHERE rsvpStatus <> 'NoResponse' AND rsvpAttendeeID = a.id) AS subStatus, primaryAttendee, note, passcode, a.token
                FROM " . PRO_ATTENDEES_TABLE . ' a
                LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                WHERE ' . $baseWhere . ' AND ( (a.rsvpEventID = %d) ';

		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
		}

		$sql .= ') ORDER BY primaryAttendee DESC';
		$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, trim( $full_name ), $rsvp_id ) );
	} else {
		$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus, email, suffix, salutation ,
                    (SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' WHERE rsvpStatus <> \'NoResponse\' AND rsvpAttendeeID = a.id) AS subStatus, primaryAttendee, note, passcode, a.token
                FROM ' . PRO_ATTENDEES_TABLE . ' a
                LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                WHERE ' . $baseWhere . ' AND ( (a.rsvpEventID = %d) ';

		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
		}

		$sql     .= ') ORDER BY primaryAttendee DESC';

		if ( ! empty( $rsvp_token ) ) {
			$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $rsvp_token, $rsvp_id ) );
		} else {
			$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $firstName, $firstName, $lastName, $rsvp_id ) );	
		}
	}

	// Check to see if the attendee(s) have access to the current event(s).
	$tmp_access = array();
	foreach( $attendee as $a ) {
		if ( rsvp_pro_does_user_have_access_to_event_or_subevents( $rsvp_id, $a->id ) ) {
			$tmp_access[] = $a;
		}
	}
	$attendee = $tmp_access;

	if ( $attendee != null ) {
		if ( count( $attendee ) > 1 ) {
			$output = rsvp_pro_get_beginning_of_frontend_container();

			$multipleText = rsvp_pro_get_frontend_string( 'multiple_people_found_text' );

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MULTIPLE_MATCHES_TEXT ) != '' ) {
				$multipleText = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MULTIPLE_MATCHES_TEXT );
			}

			$output .= RSVP_PRO_START_PARA . $hi_text . ' ' . esc_html( stripslashes( $attendee[0]->firstName . ' ' . $attendee[0]->lastName ) ) .
					   ' ' . $multipleText . RSVP_PRO_END_PARA;

			$matches_attendee_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MULTIPLE_ATTENDEE_TEXT );
			$junk_array            = array();
			foreach ( $attendee as $a ) {
				$output .= RSVP_PRO_START_PARA;
				$output .= "<form method=\"post\" action=\"{$rsvp_form_action}\">";
				$output .= '  <input type="hidden" name="rsvp_id" id="rsvp_id" value="' . $rsvp_id . '" />';
				$output .= '  <input type="hidden" value="foundattendee" name="rsvpStep' . $rsvp_id . '" />';
				$output .= '  <input type="hidden" name="attendeeID" id="attendeeID" value="' . $a->id . '" />';

				if ( ! empty( $matches_attendee_text ) ) {
					$output .= esc_html( rsvp_pro_admin_replaceVariablesForEmail( $a, '', $matches_attendee_text, $rsvp_id, $junk_array ) );
				} else {
					$output .= esc_html( stripslashes( $a->salutation . ' ' . $a->firstName . ' ' . $a->lastName . ' ' . $a->suffix ) );

					if ( ! empty( $a->email ) ) {
						$output .= ' - ' . esc_html( stripslashes( $a->email ) );
					}
				}

				$output .= ' <input type="submit" value="' . rsvp_pro_get_frontend_string( 'rsvp_button_label' ) . '" class="rsvpSubmit" />';
				$output .= '</form>' . RSVP_PRO_END_PARA;
			}

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) === 'Y' ) {
				$output .= rsvp_pro_frontend_new_attendee_button();
			}

			return rsvp_pro_handle_output( $text, $output . "</div>\r\n" );
		} else {
			$attendee = $attendee[0];
			if ( isset( $_GET['autoRsvp'] ) && ( 'Y' === strtoupper( $_GET['autoRsvp'] ) ) ) {
				$_POST['attendeeID'] = $attendee->id;

				if ( isset( $_REQUEST['rsvpStatus'] ) ) {
					$_POST['mainRsvp'] = rsvp_pro_translate_status_to_form_value( $_REQUEST['rsvpStatus'] );
				} elseif ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DEFAULT_RSVP_VALUE ) !== '' ) {
					$_POST['mainRsvp'] = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DEFAULT_RSVP_VALUE );
					$_POST['mainRsvp'] = ucfirst( $_POST['mainRsvp'] );
				}

				$output = rsvp_pro_handlersvp( $output, $text, true );

				return rsvp_pro_handle_output( $text, $output );
			}

			// hey we found something, we should move on and print out any associated users and let them rsvp.
			$output = "<div>\r\n";
			$has_rsvped = false;
			if ( rsvp_pro_is_attendee_a_global_attendee( $attendee->id ) ) {
				$sql         = 'SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' WHERE rsvpStatus <> \'NoResponse\' AND rsvpAttendeeID = %d 
				AND ( rsvpEventID = %d OR rsvpEventID IN ( SELECT id FROM ' . PRO_EVENT_TABLE . ' WHERE parentEventID = %d ) )';
				$event_count = $wpdb->get_var( $wpdb->prepare( $sql, $attendee->id, $rsvp_id, $rsvp_id ) );
				if ( $event_count > 0 ) {
					$has_rsvped = true;
				}
			} elseif ( ( strtolower( $attendee->rsvpStatus ) !== 'noresponse' ) || ( $attendee->subStatus > 0 ) ) {
				$has_rsvped = true;
			}

			if ( ( $has_rsvped === false )
				 || ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_EDIT_PROMPT ) == 'Y' ) &&
					  ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ONLY_RSVP_ONCE ) != 'Y' ) ) ) {
				$welcome_text = rsvp_pro_get_frontend_string( 'welcome_back_text' );

				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_BACK_TEXT ) != '' ) {
					$welcome_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_BACK_TEXT );
				}

				$output .= RSVP_PRO_START_PARA . sprintf(
					$welcome_text,
					esc_html( stripslashes( $attendee->firstName ) ),
					esc_html( stripslashes( $attendee->lastName ) )
				) . RSVP_PRO_END_PARA;

				if ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_WELCOME ) && ! rsvp_pro_frontend_max_limit_hit( $rsvp_id ) ) {
					if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_TEXT ) ) !== '' ) {
						$output .= RSVP_PRO_START_PARA .
								   trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_TEXT ) ) .
								   RSVP_PRO_END_PARA;
					} else {
						$output .= RSVP_PRO_START_PARA . rsvp_pro_get_frontend_string( 'welcome_text' ) . RSVP_PRO_END_PARA;
					}
				}

				$output .= rsvp_pro_frontend_main_form( $attendee->id );
			} elseif ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ONLY_RSVP_ONCE ) == 'Y' ) {
				$output .= rsvp_pro_frontend_only_once_text();
			} else {
				$output .= rsvp_pro_frontend_prompt_to_edit( $attendee );
			}

			return rsvp_pro_handle_output( $text, $output . "</div>\r\n" );
		}
	} // if($attendee != null) {

	// We did not find anyone let's try and do a rough search.
	$attendees = null;

	if ( ! $passcodeOptionEnabled && ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DISABLE_USER_SEARCH ) != 'Y' ) ) {
		for ( $i = 3; $i >= 1; -- $i ) {
			$truncFirstName = rsvp_pro_chomp_name( $firstName, $i );
			$sql            = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus 
                    FROM ' . PRO_ATTENDEES_TABLE . ' a 
                    LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = $rsvp_id 
                    WHERE SOUNDEX(lastName) = SOUNDEX('" . esc_sql( $lastName ) . "') AND 
                        firstName LIKE '" . esc_sql( $truncFirstName ) . "%' AND ( (a.rsvpEventId = $rsvp_id) ";

			if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
				$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
			}

			$sql .= ')';

			$attendees = $wpdb->get_results( $sql );
			$tmp_access = array();
			foreach( $attendees as $a ) {
				if ( rsvp_pro_does_user_have_access_to_event_or_subevents( $rsvp_id, $a->id ) ) {
					$tmp_access[] = $a;
				}
			}
			$attendees = $tmp_access;
			if ( count( $attendees ) > 0 ) {
				$fuzzyText = rsvp_pro_get_frontend_string( 'fuzzy_match_text' );

				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FUZZY_MATCH_TEXT ) != '' ) {
					$fuzzyText = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FUZZY_MATCH_TEXT );
				}
				$output = RSVP_PRO_START_PARA . '<strong>' . $fuzzyText . '</strong>' . RSVP_PRO_END_PARA;
				foreach ( $attendees as $a ) {
					$output .= "<form method=\"post\" action=\"$rsvp_form_action\">\r\n
                                    <input type=\"hidden\" name=\"rsvp_id\" id=\"rsvp_id\" value=\"$rsvp_id\" />\r\n
									<input type=\"hidden\" name=\"rsvpStep$rsvp_id\" value=\"foundattendee\" />\r\n
									<input type=\"hidden\" name=\"attendeeID\" id=\"attendeeID\" value=\"" . $a->id . "\" />\r\n
									<p class=\"rsvpParagraph\" style=\"text-align:left;\">\r\n
							" . esc_html( stripslashes( $a->firstName . ' ' . $a->lastName ) ) . "
							<input type=\"submit\" value=\"RSVP\" class=\"rsvpSubmit\" />\r\n
							</p>\r\n</form>\r\n";
				}

				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) == 'Y' ) {
					$output .= rsvp_pro_frontend_new_attendee_button();
				}

				return rsvp_pro_handle_output( $text, $output );
			} else {
				$i = strlen( $truncFirstName );
			}
		}
	}

	$notFoundText = RSVP_PRO_START_PARA . '<strong>' . sprintf( rsvp_pro_get_frontend_string( 'unable_to_find_text' ), htmlspecialchars( $firstName ), htmlspecialchars( $lastName ) ) . '</strong>' . RSVP_PRO_END_PARA;
	if ( $passcodeOnlyOption ) {
		$notFoundText = RSVP_PRO_START_PARA . '<strong>' . rsvp_pro_get_frontend_string( 'unable_to_find_passcode_text' ) . '</strong>' . RSVP_PRO_END_PARA;
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_UNABLE_TO_FIND_TEXT ) !== '' ) {
		$notFoundText = RSVP_PRO_START_PARA . '<strong>' . rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_UNABLE_TO_FIND_TEXT ) . '</strong>' . RSVP_PRO_END_PARA;
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PROMPT_TO_ADD_IF_NOT_FOUND ) === 'Y' ) {
		$rsvp_hide_new_form  = false;
		$rsvp_hide_edit_form = true;
	}

	$notFoundText .= rsvp_pro_frontend_greeting();

	return rsvp_pro_handle_output( $text, $notFoundText );
}

function rsvp_pro_editAttendee( &$output, &$text ) {
	global $wpdb;
	global $rsvp_id;

	if ( is_numeric( $_POST['attendeeID'] ) && ( $_POST['attendeeID'] > 0 ) ) {
		// Try to find the user.
		$sql = 'SELECT a.id, firstName, lastName, 
                    IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus 
                FROM ' . PRO_ATTENDEES_TABLE . ' a
                LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d
                WHERE a.id = %d AND ( (a.rsvpEventID = %d) ';

		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
		}

		$sql     .= ')';
		$attendee = $wpdb->get_row( $wpdb->prepare( $sql, $rsvp_id, $_POST['attendeeID'], $rsvp_id ) );
		if ( $attendee != null ) {
			$welcomeBackText = rsvp_pro_get_frontend_string( 'welcome_back_text' );

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_BACK_TEXT ) != '' ) {
				$welcomeBackText = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_BACK_TEXT );
			}

			$output .= rsvp_pro_get_beginning_of_frontend_container();
			$output .= RSVP_PRO_START_PARA . sprintf( $welcomeBackText, esc_html( stripslashes( $attendee->firstName ) ), esc_html( stripslashes( $attendee->lastName ) ) ) . RSVP_PRO_END_PARA;
			$output .= rsvp_pro_frontend_main_form( $attendee->id );

			return rsvp_pro_handle_output( $text, $output . RSVP_PRO_END_CONTAINER );
		}
	}
}

function rsvp_pro_foundAttendee( &$output, &$text ) {
	global $wpdb;
	global $rsvp_id;

	if ( is_numeric( $_POST['attendeeID'] ) && ( $_POST['attendeeID'] > 0 ) ) {
		$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) AS rsvpStatus,
                    (SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " 
                    WHERE rsvpStatus <> 'NoResponse' AND rsvpAttendeeID = a.id 
                    AND ( (rsvpEventID = %d) OR 
                          ( rsvpEventID IN (SELECT id FROM " . PRO_EVENT_TABLE . ' WHERE parentEventID = %d ) )
                        ) 
                    ) AS subStatus, email
                FROM ' . PRO_ATTENDEES_TABLE . ' a
                LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                WHERE a.id = %d AND ( (a.rsvpEventID = %d) ';

		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR (a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
		}

		$sql     .= ') ';
		$attendee = $wpdb->get_row( $wpdb->prepare( $sql, $rsvp_id, $rsvp_id, $rsvp_id, $_POST['attendeeID'], $rsvp_id ) );
		if ( $attendee != null ) {
			$output = rsvp_pro_get_beginning_of_frontend_container();
			if ( ( ( strtolower( $attendee->rsvpStatus ) == 'noresponse' ) && ( $attendee->subStatus <= 0 ) )
				 || ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_EDIT_PROMPT ) == 'Y' ) &&
					  ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ONLY_RSVP_ONCE ) != 'Y' ) ) ) {

				$output .= '<div class="rsvp_pro_greeting_container">';
				if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_PROFILE_ON_FORM ) ) {
					$user = get_user_by( 'email', $attendee->email );
					if ( false !== $user ) {

						$output .= '<div class="rsvp_pro_greeting_avatar">' . get_avatar( $user->ID ) . '</div>';
					}
				}
				$output .= RSVP_PRO_START_PARA . rsvp_pro_get_frontend_string( 'hi_text' ) . ' ' . htmlspecialchars( stripslashes( $attendee->firstName . ' ' . $attendee->lastName ) ) . '!' . RSVP_PRO_END_PARA;
				$output .= '</div>';

				if ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_WELCOME ) ) {
					if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_TEXT ) ) != '' ) {
						$output .= RSVP_PRO_START_PARA . trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WELCOME_TEXT ) ) . RSVP_PRO_END_PARA;
					} else {
						$output .= RSVP_PRO_START_PARA . rsvp_pro_get_frontend_string( 'welcome_text' ) . RSVP_PRO_END_PARA;
					}
				}

				$output .= rsvp_pro_frontend_main_form( $attendee->id );
			} elseif ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ONLY_RSVP_ONCE ) == 'Y' ) {
				$output .= rsvp_pro_frontend_only_once_text();
			} else {
				$output .= rsvp_pro_frontend_prompt_to_edit( $attendee );
			}

			return rsvp_pro_handle_output( $text, $output . RSVP_PRO_END_CONTAINER );
		}

		return rsvp_pro_handle_output( $text, rsvp_pro_frontend_greeting() );
	} else {
		return rsvp_pro_handle_output( $text, rsvp_pro_frontend_greeting() );
	}
}

/**
 * Generates the calendar links for the thank you page.
 *
 * @param int $attendee_id The person who RSVP'd and should have the calendar link.
 *
 * @return string          The HTML for the calendar links.
 */
function rsvp_pro_frontend_thankyou_calendar_links( $attendee_id ) {
	global $wpdb, $rsvp_id;
	$output = '';

	$gcal_text = rsvp_pro_get_frontend_string( 'google_calendar_label' );
	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GOOGLE_CALENDAR_LINK_TEXT ) != '' ) {
		$gcal_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GOOGLE_CALENDAR_LINK_TEXT );
	}

	if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_CALENDAR_LINK ) == 'Y' ) &&
		 rsvp_pro_does_user_or_associated_users_have_access_to_event( $rsvp_id, $attendee_id ) ) {
		$linkText  = rsvp_pro_get_frontend_string( 'calendar_label' );
		
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CALENDAR_LINK_TEXT ) != '' ) {
			$linkText = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CALENDAR_LINK_TEXT );
		}

		$output .= RSVP_PRO_START_PARA;
		$output .= '<a href="' . site_url() . '?rsvp_calendar_download=' . $rsvp_id . '">' . $linkText . '</a>';

		$sql        = 'SELECT id, eventName, eventStartDate, eventEndDate, eventLocation, eventDescription
            FROM ' . PRO_EVENT_TABLE . ' WHERE id = %d';
		$event_info = $wpdb->get_row( $wpdb->prepare( $sql, $rsvp_id ) );
		if ( $event_info ) {
			$output           .= ' - ';
			$event_description = stripslashes( $event_info->eventDescription );
			$event_description = rsvp_pro_get_dynamic_translated_string( rsvp_pro_get_event_name( $rsvp_id ) . ' - ' . rsvp_pro_get_admin_string( 'settings_event_description_label' ), $event_description, $rsvp_id );

			$event_location = stripslashes( $event_info->eventLocation );
			$event_location = rsvp_pro_get_dynamic_translated_string( rsvp_pro_get_event_name( $rsvp_id ) . ' - ' . rsvp_pro_get_frontend_string( 'event_location_label' ), $event_location, $rsvp_id );

			$output .= '<a href="https://www.google.com/calendar/event?action=TEMPLATE&text=' . esc_attr( rsvp_pro_get_event_name( $rsvp_id ) ) . '&dates=' . rsvp_pro_get_timezone_set_date_for_calendar( $event_info->eventStartDate ) . '/' . rsvp_pro_get_timezone_set_date_for_calendar( $event_info->eventEndDate ) . '&details=' . esc_attr( $event_description ) . '&location=' . esc_attr( $event_location ) . '&trp=false&sprop=&sprop=name:" target="_blank" rel="nofollow">' . $gcal_text . '</a>';
		}

		$output .= RSVP_PRO_END_PARA;
	}

	// Get the sub-events calendar information...
	$sql       = 'SELECT id, eventName FROM ' . PRO_EVENT_TABLE . ' WHERE parentEventID = %d';
	$subevents = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id ) );
	foreach ( $subevents as $se ) {
		if ( ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_SHOW_CALENDAR_LINK ) == 'Y' ) &&
			 rsvp_pro_does_user_or_associated_users_have_access_to_event( $se->id, $attendee_id ) ) {
			$linkText = rsvp_pro_get_frontend_string( 'calendar_label' );
			if ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_CALENDAR_LINK_TEXT ) != '' ) {
				$linkText = rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_CALENDAR_LINK_TEXT );
			}

			$output .= RSVP_PRO_START_PARA;
			$output .= '<a href="' . site_url() . '?rsvp_calendar_download=' . $se->id . '">' . $linkText . '</a>';
			$sql     = 'SELECT id, eventName, eventStartDate, eventEndDate, eventLocation, eventDescription
            FROM ' . PRO_EVENT_TABLE . ' WHERE id = %d';
			$event_info = $wpdb->get_row( $wpdb->prepare( $sql, $se->id ) );
			if ( $event_info ) {
				$output           .= ' - ';
				$event_description = stripslashes( $event_info->eventDescription );
				$event_description = rsvp_pro_get_dynamic_translated_string( rsvp_pro_get_event_name( $se->id ) . ' - ' . rsvp_pro_get_admin_string( 'settings_event_description_label' ), $event_description, $se->id );

				$event_location = stripslashes( $event_info->eventLocation );
				$event_location = rsvp_pro_get_dynamic_translated_string( rsvp_pro_get_event_name( $se->id ) . ' - ' . rsvp_pro_get_frontend_string( 'event_location_label' ), $event_location, $se->id );

				$output .= '<a href="https://www.google.com/calendar/event?action=TEMPLATE&text=' . esc_attr( rsvp_pro_get_event_name( $se->id ) ) . '&dates=' . rsvp_pro_get_timezone_set_date_for_calendar( $event_info->eventStartDate ) . '/' . rsvp_pro_get_timezone_set_date_for_calendar( $event_info->eventEndDate ) . '&details=' . esc_attr( $event_description ) . '&location=' . esc_attr( $event_location ) . '&trp=false&sprop=&sprop=name:" target="_blank" rel="nofollow">' . $gcal_text . '</a>';
			}
			$output .= RSVP_PRO_END_PARA;
		}
	}

	$params = array(
		'output'      => $output,
		'attendee_id' => $attendee_id,
		'rsvp_id'     => $rsvp_id,
	);

	$tmp_return = apply_filters( 'rsvp_pro_thank_you_calendar_text', $params );

	if ( ! is_array( $tmp_return ) ) {
		$output = $tmp_return;
	}

	return $output;
}

/**
 * Displays the thank you text when the user is done RSVP'ing.
 *
 * @param  string $thank_you_primary A string containing the primary attendee's name.
 * @param  string $thank_you_associated Asociated attendee's names.
 * @param  string $rsvp_status The RSVP status that the person RSVP'd with.
 * @param  int    $attendee_id The primary attendee's ID.
 *
 * @return string                       The thank you text for the page.
 */
function rsvp_pro_frontend_thankyou( $thank_you_primary, $thank_you_associated, $rsvp_status, $attendee_id ) {
	global $rsvp_id;
	$filter_params = array(
		'attendeeID' => $attendee_id,
		'rsvpStatus' => $rsvp_status,
		'rsvp_id'    => $rsvp_id,
	);

	$custom_ty          = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU );
	$custom_no_verbiage = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOT_COMING );

	$custom_ty          = apply_filters( 'rsvp_pro_thank_you_text', $custom_ty, $filter_params );
	$custom_no_verbiage = apply_filters( 'rsvp_pro_no_thank_you_text', $custom_no_verbiage, $filter_params );

	if ( ( 'No' === $rsvp_status ) && ! empty( $custom_no_verbiage ) ) {
		return rsvp_pro_get_beginning_of_frontend_container() . RSVP_PRO_START_PARA . nl2br( $custom_no_verbiage ) . RSVP_PRO_END_PARA . RSVP_PRO_END_CONTAINER;
	} elseif ( ! empty( $custom_ty ) ) {
		$output  = rsvp_pro_get_beginning_of_frontend_container() . RSVP_PRO_START_PARA . nl2br( $custom_ty ) . RSVP_PRO_END_PARA;
		$output .= rsvp_pro_frontend_thankyou_calendar_links( $attendee_id );
		$output .= RSVP_PRO_END_CONTAINER;

		return $output;
	} else {
		$ty_text = rsvp_pro_get_frontend_string( 'thank_you_label' );
		if ( ! empty( $thank_you_primary ) ) {
			$ty_text .= ' ' . htmlspecialchars( $thank_you_primary );
		}
		$ty_text .= rsvp_pro_get_frontend_string( 'for_rsvping' );

		if ( count( $thank_you_associated ) > 0 ) {
			$ty_text .= rsvp_pro_get_frontend_string( 'thank_you_associated_rsvping_for' );
			foreach ( $thank_you_associated as $name ) {
				$ty_text .= ' ' . htmlspecialchars( $name ) . ', ';
			}
			$ty_text = rtrim( trim( $ty_text ), ',' ) . '.';
		}
		$output  = rsvp_pro_get_beginning_of_frontend_container() . RSVP_PRO_START_PARA . $ty_text . RSVP_PRO_END_PARA;
		$output .= rsvp_pro_frontend_thankyou_calendar_links( $attendee_id );

		$output .= RSVP_PRO_END_CONTAINER;

		return $output;
	}
}

function rsvp_pro_frontend_new_attendee_thankyou( $thankYouPrimary, $thankYouAssociated, $rsvpStatus, $attendee_id, $password = '' ) {
	global $rsvp_id;

	$filterParams = array(
		'attendeeID' => $attendee_id,
		'rsvpStatus' => $rsvpStatus,
		'rsvp_id'    => $rsvp_id,
	);

	$customTy         = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU );
	$customNoVerbiage = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOT_COMING );

	$customTy         = apply_filters( 'rsvp_pro_thank_you_text', $customTy, $filterParams );
	$customNoVerbiage = apply_filters( 'rsvp_pro_no_thank_you_text', $customNoVerbiage, $filterParams );

	$thankYouText = '';

	if ( ( 'No' === $rsvpStatus ) && ! empty( $customNoVerbiage ) ) {
		$thankYouText .= nl2br( $customNoVerbiage );
	} elseif ( ! empty( $customTy ) ) {
		$thankYouText .= nl2br( $customTy );
	} else {
		$thankYouText .= rsvp_pro_get_frontend_string( 'thank_you_label' );
		if ( ! empty( $thankYouPrimary ) ) {
			$thankYouText .= ' ' . htmlspecialchars( $thankYouPrimary );
		}
		$thankYouText .= rsvp_pro_get_frontend_string( 'for_rsvping' );
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CANT_EDIT ) != 'Y' ) {
		$thankYouText .= '<p>';

		$modify_text = rsvp_pro_get_frontend_string( 'thank_you_modify_text' );

		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU_MODIFY_TEXT ) != '' ) {
			$modify_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU_MODIFY_TEXT );
		}

		$thankYouText .= $modify_text;
		if ( ! empty( $password ) ) {
			$password_text = rsvp_pro_get_frontend_string( 'thank_you_modify_password_text' );

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU_PASSWORD_TEXT ) != '' ) {
				$password_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU_PASSWORD_TEXT );
			}

			$thankYouText .= ' ' . sprintf( $password_text, $password );
		}
		$thankYouText .= "</p>\r\n";
	}

	if ( count( $thankYouAssociated ) > 0 ) {
		$thankYouText .= '<br /><br />';

		$associated_thank_you_text = rsvp_pro_get_frontend_string( 'thank_you_associated_rsvping_for' );

		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU_ASSOCIATED_TEXT ) != '' ) {
			$associated_thank_you_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU_ASSOCIATED_TEXT );
		}

		$thankYouText = $associated_thank_you_text;

		foreach ( $thankYouAssociated as $name ) {
			$thankYouText .= htmlspecialchars( ' ' . $name ) . ', ';
		}
		$thankYouText = rtrim( trim( $thankYouText ), ',' ) . '.';
	}

	$thankYouText .= rsvp_pro_frontend_thankyou_calendar_links( $attendee_id );

	return rsvp_pro_get_beginning_of_frontend_container() . RSVP_PRO_START_PARA . $thankYouText . RSVP_PRO_END_PARA . RSVP_PRO_END_CONTAINER;
}

/**
 * Returns a substring of a name with X number of characters.
 *
 * @param  string $name The name we want to get a substring of.
 * @param  int    $max_length The max length of the string we want to get.
 *
 * @return string             The sub string of the main string we wanted to get.
 */
function rsvp_pro_chomp_name( $name, $max_length ) {
	for ( $i = $max_length; $max_length >= 1; -- $i ) {
		if ( strlen( $name ) >= $i ) {
			return substr( $name, 0, $i );
		}
	}
}

/**
 * Gets the beginning of r a form field container.
 *
 * @param  string $id Specifies the ID for the container.
 * @param  string $additional_classes Any additional CSS classes that should be added to the container.
 * @param  array  $additional_attributes Defines any additional attributes that are needed in the div.
 *
 * @return string                     The beginning of the form field container.
 */
function rsvp_pro_beginning_form_field( $id, $additional_classes, $additional_attributes = array() ) {
	$attributes = '';
	foreach ( $additional_attributes as $key => $val ) {
		$attributes .= ' ' . esc_attr( $key ) . '="' . esc_attr( $val ) . '"';
	}

	return '<div ' . ( ! empty( $id ) ? 'id="' . $id . '"' : '' ) . ' class="rsvpFormField ' .
		   ( ! empty( $additional_classes ) ? $additional_classes : '' ) . '" ' . $attributes . '>';
}

/**
 * Displays the first step for the RSVP process.
 *
 * @return string The HTML the user sees the first time they load the new attendee form.
 */
function rsvp_pro_frontend_greeting() {
	global $rsvp_id;
	global $rsvp_first_name, $rsvp_last_name, $rsvp_passcode;
	global $rsvp_hide_new_form, $rsvp_hide_edit_form, $rsvp_text;

	$output = '';

	$rsvp_form_action = htmlspecialchars( rsvp_pro_getCurrentPageURL() );
	$customGreeting   = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GREETING );

	if ( ! $rsvp_hide_edit_form ) {
		$output .= RSVP_PRO_START_PARA . rsvp_pro_get_frontend_string( 'please_enter_first_last_to_rsvp' ) . RSVP_PRO_END_PARA;
	}

	if ( ! empty( $customGreeting ) ) {
		$output = RSVP_PRO_START_PARA . nl2br( $customGreeting ) . RSVP_PRO_END_PARA;
	}

	$output .= rsvp_pro_get_beginning_of_frontend_container();

	if ( rsvp_pro_frontend_max_limit_for_all_events() ) {
		return rsvp_pro_handle_max_limit_reached_message( $rsvp_id );
	}

	if ( ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_NEW_ATTENDEE_FORM_FIRST ) ) &&
		 ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) ) ) {
		return rsvp_pro_handlenewattendee( $output, $rsvp_text );
	}

	if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) == 'Y' ) && ! $rsvp_hide_new_form ) {
		if ( $rsvp_hide_edit_form && ! $rsvp_hide_new_form && ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PROMPT_TO_ADD_IF_NOT_FOUND ) !== 'Y' ) ) {
			return rsvp_pro_handlenewattendee( $output, $rsvp_text );
		}

		$output .= rsvp_pro_frontend_new_attendee_button();
	}
	if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CANT_EDIT ) != 'Y' ) && ( ! $rsvp_hide_edit_form ) ) {
		$output .= rsvp_pro_find_attendee_form();
	}
	$output .= RSVP_PRO_END_CONTAINER;

	return $output;
}

/**
 * Displays the RSVP find attendee form.
 *
 * @return string The RSVP Find form.
 */
function rsvp_pro_find_attendee_form() {
	global $rsvp_id;
	global $rsvp_first_name, $rsvp_last_name, $rsvp_passcode;
	global $rsvp_hide_new_form, $rsvp_hide_edit_form;

	$first_name       = '';
	$last_name        = '';
	$passcode         = '';
	$output           = '';
	$rsvp_form_action = htmlspecialchars( rsvp_pro_getCurrentPageURL() );
	if ( ! empty( $rsvp_first_name ) ) {
		$first_name = $rsvp_first_name;
	}
	if ( ! empty( $rsvp_last_name ) ) {
		$last_name = $rsvp_last_name;
	}
	if ( ! empty( $rsvp_passcode ) ) {
		$passcode = $rsvp_passcode;
	}

	$existing_attendee_additional_css = '';
	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_SEARCH_FORM ) == 'Y' && empty( $first_name ) && empty( $last_name ) && empty( $passcode ) ) {
		$find_attendees_button_text = rsvp_pro_get_frontend_string( 'find_attendees_button_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DISPLAY_SEARCH_FORM_TEXT ) != '' ) {
			$find_attendees_button_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DISPLAY_SEARCH_FORM_TEXT );
		}
		$existing_attendee_additional_css = 'hide_form';

		$output .= '<div id="rsvp_toggle_attendee_container"><button id="rsvp_toggle_attendee_search">' . $find_attendees_button_text . '</button></div>';
	}

	$output .= '<div id="rsvp_existing_attendee_form" class="' . $existing_attendee_additional_css . '">';
	if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_OPEN_REGISTRATION ) == 'Y' ) && ! $rsvp_hide_new_form ) {
		$output  .= '<hr />';
		$tmp_text = rsvp_pro_get_frontend_string( 'modify_registration_text' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MODIFY_REGISTRATION_TEXT ) != '' ) {
			$tmp_text = stripslashes_deep( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MODIFY_REGISTRATION_TEXT ) );
		}
		$output .= RSVP_PRO_START_PARA . $tmp_text . RSVP_PRO_END_PARA;
	}

	$output .= "<form name=\"rsvp\" method=\"post\" id=\"rsvp\" action=\"$rsvp_form_action\" autocomplete=\"off\">\r\n";
	$output .= '  <input type="hidden" name="rsvp_id" id="rsvp_id" value="' . $rsvp_id . '" />';
	$output .= '	<input type="hidden" name="rsvpStep' . $rsvp_id . '" value="find" />';

	if ( ! rsvp_pro_require_only_passcode_to_register( $rsvp_id ) &&
		 ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ATTENDEE_LOOKUP_VIA_EMAIL ) !== 'Y' ) &&
		 ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FULL_NAME_SEARCH ) ) ) {
		$firstNameLabel = rsvp_pro_get_frontend_string( 'first_name_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_NAME_LABEL ) !== '' ) {
			$firstNameLabel = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_NAME_LABEL );
		}

		$lastNameLabel = rsvp_pro_get_frontend_string( 'last_name_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_LABEL ) !== '' ) {
			$lastNameLabel = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_LABEL );
		}

		$output .= rsvp_pro_beginning_form_field( '', '' ) . '<label for="firstName">' . $firstNameLabel . '</label>
			<input type="text" name="firstName" id="firstName" size="30" value="' . esc_html( stripslashes_deep( $first_name ) ) . '" class="required" />' . RSVP_PRO_END_FORM_FIELD;
		$output .= rsvp_pro_beginning_form_field( '', '' ) . '<label for="lastName">' . $lastNameLabel . '</label>
  								 <input type="text" name="lastName" id="lastName" size="30" value="' . esc_html( stripslashes_deep( $last_name ) ) . '" class="' . ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_NOT_REQUIRED ) !== 'Y' ) ? 'required' : '' ) . '" />' . RSVP_PRO_END_FORM_FIELD;
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FULL_NAME_SEARCH ) ) {
		$full_name_label = rsvp_pro_get_frontend_string( 'name_label' );
		if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NAME_LABEL ) ) {
			$full_name_label = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NAME_LABEL );
		}

		$output .= rsvp_pro_beginning_form_field( '', '' ) . '<label for="full_name">' . $full_name_label . '</label>
			<input type="text" name="full_name" id="full_name" size="30" value="'. esc_html( stripslashes_deep( $first_name . ' ' . $last_name ) ) . '" class="required" />' . RSVP_PRO_END_FORM_FIELD;
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ATTENDEE_LOOKUP_VIA_EMAIL ) == 'Y' ) {
		$emailLabel = rsvp_pro_get_frontend_string( 'email_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_LABEL ) != '' ) {
			$emailLabel = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_LABEL );
		}

		$output .= rsvp_pro_beginning_form_field( '', '' ) . '<label for="email">' . esc_html( $emailLabel ) . '</label>
                <input type="text" name="email" id="email" size="30" class="required" />' . RSVP_PRO_END_FORM_FIELD;
	}

	if ( rsvp_pro_require_passcode( $rsvp_id ) ) {
		$passcodeLabel = rsvp_pro_get_frontend_string( 'passcode_label' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_LABEL ) != '' ) {
			$passcodeLabel = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_LABEL );
		}
		$output .= rsvp_pro_beginning_form_field( '', '' ) . '<label for="passcode">' . $passcodeLabel . '</label>
			<input type="password" name="passcode" id="passcode" size="30" value="' . esc_html( $passcode ) . '" class="required" autocomplete="off" />' . RSVP_PRO_END_FORM_FIELD;
	}

	$button_text = rsvp_pro_get_frontend_string( 'find_me_label' );
	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_COMPLETE_BUTTON_TEXT ) != '' ) {
		$button_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_COMPLETE_BUTTON_TEXT );
	}

	$output .= '<p class="rsvpParagraph rsvpSubmitContainer"><input type="submit" value="' . $button_text . '" class="rsvpSubmit" />' . RSVP_PRO_END_PARA;
	$output .= "</form>\r\n";
	$output .= "</div>\r\n";

	return $output;
}

/**
 * Retrieves the email body for an attendee email.
 *
 * @param  int    $attendee_id The attendee ID we are generating the email body for.
 * @param  object $attendee    A database row with the information for an attendee.
 * @return string              An HTML formatted email body.
 */
function rsvp_pro_retrieveEmailBodyContent( $attendee_id, $attendee ) {
	global $wpdb, $rsvp_id;
	$body                     = '';
	$has_access_to_main_event = does_user_have_access_to_event( $rsvp_id, $attendee_id );
	if ( $has_access_to_main_event ) {
		$body .= '<p>' . rsvp_pro_get_event_information( $rsvp_id, RSVP_PRO_INFO_EVENT_NAME ) . esc_html__( ' RSVP Status', 'rsvp-pro-plugin' ) . ': <b>' . rsvp_pro_get_event_status( $attendee->rsvpStatus, $rsvp_id, false ) . '</b></p>';
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SALUTATION ) && ( '' !== $attendee->salutation ) ) {
		$body .= '<p>' . esc_html__( 'Salutation', 'rsvp-pro-plugin' ) . ': ' . $attendee->salutation . '</p>';
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SUFFIX ) && ( '' !== $attendee->suffix ) ) {
		$body .= '<p>' . esc_html__( 'Suffix', 'rsvp-pro-plugin' ) . ': ' . $attendee->suffix . '</p>';
	}

	if ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_HIDE_EMAIL_FIELD ) ) {
		$body .= '<p>' . esc_html__( 'Email', 'rsvp-pro-plugin' ) . ': ' . stripslashes_deep( $attendee->email ) . '</p>';
	}

	if ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_NOTE ) ) {
		$body .= '<p>' . esc_html__( 'Note', 'rsvp-pro-plugin' ) . ': ' . stripslashes( $attendee->note ) . '</p>';
	}

	if ( !empty( $attendee->passcode ) && rsvp_pro_require_passcode( $rsvp_id ) ) {
		$body .= '<p>' . esc_html__( 'Passcode', 'rsvp-pro-plugin' ) . ': ' . stripslashes( $attendee->passcode ) . '</p>';
	}

	if ( $has_access_to_main_event ) {
		$sql = 'SELECT q.id, question, answer, q.sortOrder FROM ' . PRO_QUESTIONS_TABLE . ' q
    	LEFT JOIN ' . PRO_QUESTION_TYPE_TABLE . ' qt ON qt.id = q.questionTypeID
			LEFT JOIN ' . PRO_ATTENDEE_ANSWERS . " ans ON q.id = ans.questionID AND ans.attendeeID = %d
    	WHERE q.rsvpEventID = %d
			AND (q.permissionLevel = 'public'
			OR (q.permissionLevel = 'private' AND q.id IN (SELECT questionID FROM " . PRO_QUESTION_ATTENDEES_TABLE . " WHERE attendeeID = %d)))
    	AND qt.questionType NOT IN ('readonly', 'hidden')
    	ORDER BY sortOrder, id";
		$aRs = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $rsvp_id, $attendee_id ) );
		if ( count( $aRs ) > 0 ) {
			$body .= '<h4>'.esc_html__('Custom Question Answers','rsvp-pro-plugin').'</h4>';
			$body .= '<ul>';
			foreach ( $aRs as $a ) {
				$body .= '<li>' . stripslashes_deep( $a->question ) . ': ' . stripslashes_deep( $a->answer ) . '</li>';
			}
			$body .= '</ul>';
		}
	}

	$sql       = 'SELECT eventName, e.id, rsvpStatus
		FROM ' . PRO_EVENT_TABLE . ' e
		INNER JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " se ON se.rsvpEventID = e.id AND se.rsvpAttendeeID = %d
		WHERE e.parentEventID = %d AND ((e.event_access != '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "') OR
		se.rsvpAttendeeID IN (SELECT rsvpAttendeeID FROM " . PRO_EVENT_ATTENDEE_TABLE . ' WHERE rsvpEventID = e.id))';
	$subevents = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $rsvp_id ) );
	foreach ( $subevents as $se ) {
		$body .= '<h3>' . stripslashes_deep( $se->eventName ) . ' Information</h3>';
		$body .= '<p>'.esc_html__('RSVP Status','rsvp-pro-plugin').': <b>' . rsvp_pro_get_event_status( $se->rsvpStatus, $se->id, true ) . '</b></p>';

		$sql = 'SELECT q.id, question, answer, q.sortOrder FROM ' . PRO_QUESTIONS_TABLE . ' q
	    LEFT JOIN ' . PRO_QUESTION_TYPE_TABLE . ' qt ON qt.id = q.questionTypeID
			LEFT JOIN ' . PRO_ATTENDEE_ANSWERS . " ans ON q.id = ans.questionID AND ans.attendeeID = %d
	    WHERE q.rsvpEventID = %d
			AND (q.permissionLevel = 'public'
			  OR (q.permissionLevel = 'private' AND q.id IN (SELECT questionID FROM " . PRO_QUESTION_ATTENDEES_TABLE . " WHERE attendeeID = %d)))
	    AND qt.questionType NOT IN ('readonly', 'hidden')
	    ORDER BY sortOrder, id";
		$aRs = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $se->id, $attendee_id ) );
		if ( count( $aRs ) > 0 ) {
			$body .= '<h4>'.esc_html__('Custom Question Answers','rsvp-pro-plugin').'</h4>';
			$body .= '<ul>';
			foreach ( $aRs as $a ) {
				$body .= '<li>' . stripslashes_deep( $a->question ) . ': ' . stripslashes_deep( $a->answer ) . '</li>';
			}
			$body .= '</ul>';
		}
	}

	$sql = 'SELECT firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) as rsvpStatus, 
        a.id, passcode, note, salutation, suffix, a.email  
    FROM ' . PRO_ATTENDEES_TABLE . ' a
    LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
    WHERE (a.id IN (SELECT attendeeID FROM ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' WHERE associatedAttendeeID = %d)
    OR a.id in (SELECT associatedAttendeeID FROM ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' WHERE attendeeID = %d) OR
    a.id IN (SELECT waa1.attendeeID FROM ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' waa1
    INNER JOIN ' . PRO_ASSOCIATED_ATTENDEES_TABLE . ' waa2 ON waa2.attendeeID = waa1.attendeeID  OR
    waa1.associatedAttendeeID = waa2.attendeeID
    WHERE waa2.associatedAttendeeID = %d AND waa1.attendeeID <> %d)) AND ( (a.rsvpEventID = %d) ';

	if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
		$sql .= ' OR ( a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ') ';
	}

	$sql .= ')';

	$associations = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $attendee_id, $attendee_id, $attendee_id, $attendee_id, $rsvp_id ) );
	if ( count( $associations ) > 0 ) {
		$body .= '<br />';
		$body .= '<h3>'.esc_html__('Associated Attendees','rsvp-pro-plugin').'</h3>';
		foreach ( $associations as $a ) {
			$has_access_to_main_event = does_user_have_access_to_event( $rsvp_id, $a->id );
			$body                    .= '<hr />';
			$body                    .= '<p>'.esc_html__('Attendee Name','rsvp-pro-plugin').': <b>' . stripslashes_deep( $a->firstName . ' ' . $a->lastName ) . '</b></p>';
			if ( $has_access_to_main_event ) {
				$body .= '<p>' . rsvp_pro_get_event_information( $rsvp_id, RSVP_PRO_INFO_EVENT_NAME ) . ' '.esc_html__('RSVP Status','rsvp-pro-plugin').': <b>' . rsvp_pro_get_event_status( $a->rsvpStatus, $rsvp_id, false ) . '</b></p>';
			}

			if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SALUTATION ) && ( '' !== $a->salutation ) ) {
				$body .= '<p>'.esc_html__('Salutation','rsvp-pro-plugin').': ' . $a->salutation . '</p>';
			}

			if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SUFFIX ) && ( '' !== $a->suffix ) ) {
				$body .= '<p>'.esc_html__('Suffix','rsvp-pro-plugin').': ' . $a->suffix . '</p>';
			}

			if ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_HIDE_EMAIL_FIELD) ) {
				$body .= '<p>'.esc_html__('Email','rsvp-pro-plugin').': ' . stripslashes_deep( $a->email ) . '</p>';
			}

			if ( 'Y' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_NOTE ) ) {
				$body .= '<p>'.esc_html__('Note','rsvp-pro-plugin').': ' . stripslashes_deep( $a->note ) . '</p>';
			}

			if ( ! empty( $a->passcode ) && rsvp_pro_require_passcode( $rsvp_id ) ) {
				$body .= '<p>'.esc_html__('Passcode','rsvp-pro-plugin').': ' . stripslashes( $a->passcode ) . '</p>';
			}

			if ( $has_access_to_main_event ) :
				// Get Questions...
				$sql = 'SELECT q.id, question, answer, q.sortOrder FROM ' . PRO_QUESTIONS_TABLE . ' q
	        			LEFT JOIN ' . PRO_QUESTION_TYPE_TABLE . ' qt ON qt.id = q.questionTypeID
						LEFT JOIN ' . PRO_ATTENDEE_ANSWERS . " ans ON q.id = ans.questionID AND ans.attendeeID = %d
	        			WHERE q.rsvpEventID = %d
	    					AND (q.permissionLevel = 'public'
	    		  			OR (q.permissionLevel = 'private' AND q.id IN (SELECT questionID FROM " . PRO_QUESTION_ATTENDEES_TABLE . " WHERE attendeeID = %d)))
	        			AND qt.questionType NOT IN ('readonly', 'hidden')
	        			ORDER BY sortOrder, id";
				$aRs = $wpdb->get_results( $wpdb->prepare( $sql, $a->id, $rsvp_id, $a->id ) );
				if ( count( $aRs ) > 0 ) {
					$body .= '<h4>'.esc_html__('Custom Question Answers','rsvp-pro-plugin').'</h4>';
					$body .= '<ul>';
					foreach ( $aRs as $ans ) {
						$body .= '<li>' . stripslashes_deep( $ans->question ) . ': ' . stripslashes_deep( $ans->answer ) . '</li>';
					}
					$body .= '</ul>';
				}
			endif;

			$sql       = 'SELECT eventName, e.id, rsvpStatus
        			FROM ' . PRO_EVENT_TABLE . ' e
        			INNER JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " se ON se.rsvpEventID = e.id AND se.rsvpAttendeeID = %d
        			WHERE e.parentEventID = %d AND ((e.event_access != '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "') OR
        				se.rsvpAttendeeID IN (SELECT rsvpAttendeeID FROM " . PRO_EVENT_ATTENDEE_TABLE . ' WHERE rsvpEventID = e.id))';
			$subevents = $wpdb->get_results( $wpdb->prepare( $sql, $a->id, $rsvp_id ) );
			foreach ( $subevents as $se ) {
				$body .= '<h3>' . stripslashes_deep( $se->eventName ) . ' Information</h3>';
				$body .= '<p>'.esc_html__('RSVP Status','rsvp-pro-plugin').': <b>' . rsvp_pro_get_event_status( $se->rsvpStatus, $se->id, true ) . '</b></p>';

				$sql = 'SELECT q.id, question, answer, q.sortOrder FROM ' . PRO_QUESTIONS_TABLE . ' q
		        LEFT JOIN ' . PRO_QUESTION_TYPE_TABLE . ' qt ON qt.id = q.questionTypeID
						LEFT JOIN ' . PRO_ATTENDEE_ANSWERS . " ans ON q.id = ans.questionID AND ans.attendeeID = %d
		        WHERE q.rsvpEventID = %d
		    		AND (q.permissionLevel = 'public'
		    		  OR (q.permissionLevel = 'private' AND q.id IN (SELECT questionID FROM " . PRO_QUESTION_ATTENDEES_TABLE . " WHERE attendeeID = %d)))
		        AND qt.questionType NOT IN ('readonly', 'hidden')
		        		ORDER BY sortOrder, id";
				$aRs = $wpdb->get_results( $wpdb->prepare( $sql, $a->id, $se->id, $a->id ) );
				if ( count( $aRs ) > 0 ) {
					$body .= '<h4>'.esc_html__('Custom Question Answers','rsvp-pro-plugin').'</h4>';
					$body .= '<ul>';
					foreach ( $aRs as $ans ) {
						$body .= '<li>' . stripslashes_deep( $ans->question ) . ': ' . stripslashes_deep( $ans->answer ) . '</li>';
					}
					$body .= '</ul>';
				}
			}
		}
	}

	return $body;
}

/*
 * Checks to see if the max limit is set and if so returns true or false depending on if the limit is hit
 */
function rsvp_pro_frontend_max_limit_hit( $rsvp_event_id ) {
	global $wpdb, $attendee_count;

	$maxLimit   = array();
	$isSubEvent = rsvp_pro_is_sub_event( $rsvp_event_id );
	$function   = 'rsvp_pro_get_event_option';

	if ( $isSubEvent ) {
		$function = 'rsvp_pro_get_sub_event_option';
	}

	$tmpLimit = $function( $rsvp_event_id, RSVP_PRO_OPTION_EVENT_COUNT_LIMIT );

	if ( ( $function( $rsvp_event_id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) == 'Y' ) && ( $function( $rsvp_event_id, RSVP_PRO_OPTION_WAITLIST_YES_UNAVAILABLE ) == 'Y' ) && ( $function( $rsvp_event_id, RSVP_PRO_OPTION_WAITLIST_PERM_SWITCH ) == 'Y' ) ) {
		return true;
	}

	if ( is_numeric( $tmpLimit ) && ( $tmpLimit > 0 ) ) {
		$maxLimit[ $rsvp_event_id ] = $tmpLimit;
	}

	if ( count( $maxLimit ) > 0 ) {
		// We will cache the attendee count per request to minimize query hits. This isn't great
		// as it could cause a race condition but this is a trade-off we will have to take
		if ( ! isset( $attendee_count[ $rsvp_event_id ] ) || ( $attendee_count[ $rsvp_event_id ] <= 0 ) ) {
			if ( $isSubEvent ) {
				$sql = 'SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' ase
				JOIN ' . PRO_ATTENDEES_TABLE . " a ON a.id = ase.rsvpAttendeeID
				WHERE ase.rsvpStatus = 'Yes' AND ase.rsvpEventID = %d";
			} else {
				$sql = 'SELECT COUNT(*) FROM ' . PRO_ATTENDEES_TABLE . " WHERE (rsvpStatus = 'Yes' AND rsvpEventID = %d) ";

				if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
					$sql .= ' OR id IN (
                    SELECT rsvpAttendeeID 
                    FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " WHERE rsvpStatus = 'Yes' AND rsvpEventID = %d )";
				}
			}

			if ( rsvp_pro_is_shared_attendee_list_enabled() && ! $isSubEvent ) {
				$attendee_count[ $rsvp_event_id ] = $wpdb->get_var( $wpdb->prepare( $sql, $rsvp_event_id, $rsvp_event_id ) );
			} else {
				$attendee_count[ $rsvp_event_id ] = $wpdb->get_var( $wpdb->prepare( $sql, $rsvp_event_id ) );
			}
		}

		if ( $attendee_count[ $rsvp_event_id ] >= $maxLimit[ $rsvp_event_id ] ) {
			if ( ( $function( $rsvp_event_id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) == 'Y' ) && ( $function( $rsvp_event_id, RSVP_PRO_OPTION_WAITLIST_PERM_SWITCH ) == 'Y' ) && ( $function( $rsvp_event_id, RSVP_PRO_OPTION_WAITLIST_YES_UNAVAILABLE ) != 'Y' ) ) {
				rsvp_pro_set_yes_unavailable( $rsvp_event_id );
			}

			return true;
		} else {
			return false;
		}
	}

	return false;
}

/**
 * Handles the messaging for when a max limit has been reached and we need to stop moving forward.
 *
 * @param  int $rsvp_event_id the current rsvp id.
 *
 * @return string                The max limit reach message if any.
 */
function rsvp_pro_handle_max_limit_reached_message( $rsvp_event_id ) {
	$isSubEvent = rsvp_pro_is_sub_event( $rsvp_event_id );

	$function = 'rsvp_pro_get_event_option';

	if ( $isSubEvent ) {
		$function = 'rsvp_pro_get_sub_event_option';
	}

	$max_count     = $function( $rsvp_event_id, RSVP_PRO_OPTION_EVENT_COUNT_LIMIT );
	$limit_message = rsvp_pro_get_frontend_string( 'max_limit_message' );
	if ( '' !== $function( $rsvp_event_id, RSVP_PRO_OPTION_MAX_COUNT_REACHED_TEXT ) ) {
		$limit_message = $function( $rsvp_event_id, RSVP_PRO_OPTION_MAX_COUNT_REACHED_TEXT );
	}
	$limit_message = sprintf( $limit_message, $max_count );

	$output = rsvp_pro_beginning_form_field( 'rsvp_pro_limit_message', 'rsvp_pro_waitlist_limit_message' ) .
			  RSVP_PRO_START_PARA . $limit_message . RSVP_PRO_END_PARA .
			  RSVP_PRO_END_CONTAINER;

	return $output;
}

/**
 * Gets the waitlist message if it is enabled.
 *
 * @param  int $rsvpEventId The RSVP Event ID we want to get the message for.
 *
 * @return string           The waitlist message or an empty string.
 */
function rsvp_pro_handle_waitlist_message( $rsvpEventId ) {
	$isSubEvent = rsvp_pro_is_sub_event( $rsvpEventId );
	$function   = 'rsvp_pro_get_event_option';

	if ( $isSubEvent ) {
		$function = 'rsvp_pro_get_sub_event_option';
	}

	$message = '';
	if ( $function( $rsvpEventId, RSVP_PRO_OPTION_ENABLE_WAITLIST ) == 'Y' ) {
		if ( $function( $rsvpEventId, RSVP_PRO_OPTION_WAITLIST_TEXT ) != '' ) {
			$message = $function( $rsvpEventId, RSVP_PRO_OPTION_WAITLIST_TEXT );
		} else {
			$message = rsvp_pro_get_frontend_string( 'waitlist_available_message' );
		}

		$message = rsvp_pro_beginning_form_field( 'rsvp_pro_waitlist_message', 'rsvp_pro_waitlist_message' ) .
				   RSVP_PRO_START_PARA . $message . RSVP_PRO_END_PARA .
				   RSVP_PRO_END_CONTAINER;
	}

	return $message;
}

function rsvp_pro_frontend_max_limit_for_all_events() {
	global $wpdb, $rsvp_id, $attendee_count;

	$maxLimits = array();

	$isParentEvent = rsvp_pro_is_parent_event( $rsvp_id );
	$tmpLimit      = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EVENT_COUNT_LIMIT );
	$subEvents     = array();
	if ( is_numeric( $tmpLimit ) && ( $tmpLimit > 0 ) && ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) != 'Y' ) ) {
		$maxLimits[ $rsvp_id ] = $tmpLimit;
	}

	if ( $isParentEvent ) {
		// Get all the sub-events max limits or if they don't have a max limit
		// return false right away...
		$subEvents = $wpdb->get_results( $wpdb->prepare( 'SELECT id FROM ' . PRO_EVENT_TABLE . ' WHERE parentEventID = %d', $rsvp_id ) );
		foreach ( $subEvents as $se ) {
			$tmpLimit = rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_EVENT_COUNT_LIMIT );
			if ( is_numeric( $tmpLimit ) && ( $tmpLimit > 0 ) && ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) != 'Y' ) ) {
				$maxLimits[ $se->id ] = $tmpLimit;
			} else {
				// No max limit for this sub-event no need to go on as this event will always
				// be able to take attendees
				return false;
			}
		}
	}

	if ( count( $maxLimits ) > 0 ) {
		if ( ! isset( $attendee_count[ $rsvp_id ] ) || ( $attendee_count[ $rsvp_id ] < 0 ) ) {
			$sql                        = 'SELECT COUNT(*) FROM ' . PRO_ATTENDEES_TABLE . " WHERE rsvpStatus = 'Yes' AND rsvpEventID = %d";
			$attendee_count[ $rsvp_id ] = $wpdb->get_var( $wpdb->prepare( $sql, $rsvp_id ) );
			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) == 'Y' ) && ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WAITLIST_PERM_SWITCH ) == 'Y' ) && ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WAITLIST_YES_UNAVAILABLE ) == 'Y' ) ) {
				$attendee_count[ $rsvp_id ] = $maxLimits[ $rsvp_id ];
			}
		}

		if ( $isParentEvent ) {
			foreach ( $subEvents as $se ) {
				$sql                       = 'SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' ase
				JOIN ' . PRO_ATTENDEES_TABLE . " a ON a.id = ase.rsvpAttendeeID
				WHERE ase.rsvpStatus = 'Yes' AND ase.rsvpEventID = %d";
				$attendee_count[ $se->id ] = $wpdb->get_var( $wpdb->prepare( $sql, $se->id ) );
				if ( ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) == 'Y' ) && ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_WAITLIST_PERM_SWITCH ) == 'Y' ) && ( rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_WAITLIST_YES_UNAVAILABLE ) == 'Y' ) ) {
					$attendee_count[ $se->id ] = $maxLimits[ $se->id ];
				}
			}
		}

		foreach ( $attendee_count as $key => $val ) {
			if ( $maxLimits[ $key ] > $val ) {
				return false;
			}
		}

		return true;
	}

	return false;
}

function rsvp_pro_autologin_frontend( $rsvp_id ) {
	global $wpdb;

	$foundAttendeeId = 0;
	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_AUTO_LOGIN_ATTENDEE ) == 'Y' ) {
		$current_user = wp_get_current_user();
		if ( ( $current_user instanceof WP_User ) && ( $current_user->ID > 0 ) ) {
			$sql = 'SELECT a.id FROM ' . PRO_ATTENDEES_TABLE . ' a 
                WHERE email = %s AND ( ( rsvpEventID = %d ) ';

			if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
				$sql .= ' OR ( rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ' ) ';
			}
			$sql .= ' ) ';
			$aId  = $wpdb->get_var( $wpdb->prepare( $sql, $current_user->user_email, $rsvp_id ) );

			if ( $aId > 0 ) {
				$foundAttendeeId = $aId;
			}
		}
	}

	return $foundAttendeeId;
}

/**
 * Checks to see if user should auto enroll based on the current WP user.
 *
 * @param  int     $rsvp_id The current RSVP event ID.
 * @param  WP_User $current_user The current WordPress user.
 *
 * @return boolean               If the current user should be auto-enrolled.
 */
function rsvp_pro_current_user_auto_enroll( $rsvp_id, $current_user ) {
	$auto_roles = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_AUTO_ENROLL_ROLE );
	if ( is_array( $auto_roles ) && ( count( $auto_roles ) > 0 ) ) {
		foreach ( $auto_roles as $r ) {
			if ( in_array( $r, $current_user->roles ) ) {
				return true;
			}
		}
	}

	return false;
}

/**
 * Handles the email notifications that should be sent to attendees.
 *
 * @param  int     $attendee_id The main attendee ID that we are sending the notification to.
 * @param  int     $rsvp_id The main RSVP event ID we are sending the notification for.
 * @param  boolean $associated_attendee If the attendee is an associated attendee.
 */
function rsvp_pro_frontend_handle_email_notifications( $attendee_id, $rsvp_id, $associated_attendee = false ) {
	global $wpdb;

	$email = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOTIFY_EMAIL );

	if ( '' === $email ) {
		$email = get_option( 'admin_email' );
	}

	if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOTIFY_ON_RSVP ) == 'Y' ) && ( $email != '' ) ) {
		$sql = 'SELECT a.id, firstName, lastName, IFNULL(se.rsvpStatus, a.rsvpStatus) as rsvpStatus, 
                    note, passcode, salutation, suffix, a.token, email  
                FROM ' . PRO_ATTENDEES_TABLE . ' a 
                LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                WHERE a.id= %d AND ( (a.rsvpEventID = %d) ';

		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR ( a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ' ) ';
		}

		$sql     .= ')';
		$attendee = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $attendee_id, $rsvp_id ) );
		if ( count( $attendee ) > 0 ) {
			$body     = '<html><head><title></title></head><body>';
			$body    .= '<p>'.esc_html__('Hello','rsvp-pro-plugin').',<br /><br />';
			$attendee = $attendee[0];
			$body    .= '<b>' . stripslashes_deep( $attendee->firstName ) . ' ' . stripslashes_deep( $attendee->lastName ) .
						'</b> '.esc_html__('has submitted their RSVP','rsvp-pro-plugin').'</p>';

			$body .= rsvp_pro_retrieveEmailBodyContent( $attendee_id, $attendee );

			$headers = array( 'Content-Type: text/html; charset=UTF-8' );
			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) != '' ) {
				$headers[] = 'From: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
				$headers[] = 'Reply-To: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
				$headers[] = 'Return-Path: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
			}

			$subject = rsvp_pro_get_frontend_string( 'rsvp_admin_email_subject' );
			$subject .= ' :: ' . rsvp_pro_get_event_name( $rsvp_id ) . ' - ' . stripslashes_deep( $attendee->firstName ) . ' ' . stripslashes_deep( $attendee->lastName );
			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ADMIN_EMAIL_SUBJECT ) != '' ) {
				$subject = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ADMIN_EMAIL_SUBJECT );
			}
			$subject = apply_filters( 'rsvp_pro_admin_notify_subject', $subject );

			$body .= '</body></html>';
			$body  = nl2br( $body );

			if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ADMIN_EMAIL_BODY ) ) {
				$body        = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ADMIN_EMAIL_BODY );
				$event_url   = rsvp_pro_get_event_permalink( $rsvp_id );
				$attachments = array();
				$body        = rsvp_pro_admin_replaceVariablesForEmail( $attendee, $event_url, $body, $rsvp_id, $attachments );
			}

			$body = apply_filters( 'rsvp_pro_admin_notify_body', $body );

			$attachments = array();
			$attachments = apply_filters( 'rsvp_pro_admin_notify_attachments', $attachments );

			$headers = apply_filters( 'rsvp_pro_admin_notify_headers', $headers );

			rsvp_pro_send_mail( $email, $subject, $body, $headers, $attachments );
		}
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_GUEST_EMAIL_CONFIRMATION ) == 'Y' ) {
		$sql = 'SELECT firstName, lastName, email, IFNULL(se.rsvpStatus, a.rsvpStatus) as rsvpStatus, 
                    passcode, salutation, suffix, note, a.id, a.token
  			       FROM ' . PRO_ATTENDEES_TABLE . ' a 
                   LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                   WHERE a.id= %d AND email != '' AND ( (a.rsvpEventID = %d)";

		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR ( a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ' ) ';
		}

		$sql        .= ')';
		$attendee    = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id, $attendee_id, $rsvp_id ) );
		$attachments = array();

		if ( count( $attendee ) > 0 ) {
			$attendee  = $attendee[0];
			$event_url = rsvp_pro_get_event_permalink( $rsvp_id );
			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_EMAIL_BODY ) != '' ) &&
				 ( strtolower( $attendee->rsvpStatus ) == 'no' ) ) {
				$content  = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_EMAIL_BODY );
				$content  = stripslashes( $content );
				$key_name = rsvp_pro_get_event_name( $rsvp_id ) . ' - ' . rsvp_pro_get_admin_string( 'settings_email_attendee_body_no_label' );
				$content  = rsvp_pro_get_dynamic_translated_string( $key_name, $content, $rsvp_id );

				$body = rsvp_pro_admin_replaceVariablesForEmail( $attendee, $event_url, $content, $rsvp_id, $attachments );
			} elseif ( ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WAITLIST_EMAIL_BODY ) ) &&
					   ( strtolower( $attendee->rsvpStatus ) === 'waitlist' ) ) {
				$content  = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WAITLIST_EMAIL_BODY );
				$content  = stripslashes( $content );
				$key_name = rsvp_pro_get_event_name( $rsvp_id ) . ' - ' . rsvp_pro_get_admin_string( 'settings_email_attendee_body_waitlist_label' );
				$content  = rsvp_pro_get_dynamic_translated_string( $key_name, $content, $rsvp_id );

				$body = rsvp_pro_admin_replaceVariablesForEmail( $attendee, $event_url, $content, $rsvp_id, $attachments );
			} elseif ( ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MAYBE_EMAIL_BODY ) ) &&
					   ( strtolower( $attendee->rsvpStatus ) === 'maybe' ) ) {
				$content  = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MAYBE_EMAIL_BODY );
				$content  = stripslashes( $content );
				$key_name = rsvp_pro_get_event_name( $rsvp_id ) . ' - ' . rsvp_pro_get_admin_string( 'settings_email_attendee_body_maybe_label' );
				$content  = rsvp_pro_get_dynamic_translated_string( $key_name, $content, $rsvp_id );

				$body = rsvp_pro_admin_replaceVariablesForEmail( $attendee, $event_url, $content, $rsvp_id, $attachments );
			} elseif ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_BODY ) != '' ) {
				$content  = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_BODY );
				$content  = stripslashes( $content );
				$key_name = rsvp_pro_get_event_name( $rsvp_id ) . ' - ' . rsvp_pro_get_admin_string( 'settings_email_attendee_body_label' );
				$content  = rsvp_pro_get_dynamic_translated_string( $key_name, $content, $rsvp_id );

				$body = rsvp_pro_admin_replaceVariablesForEmail( $attendee, $event_url, $content, $rsvp_id, $attachments );
			} else {
				$body = '<html><head><title></title></head><body>' .
					'<p>Hello ';
				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SALUTATION ) == 'Y' ) {
					$body .= stripslashes( $attendee->salutation ) . ' ';
				}
				$body .= stripslashes( $attendee->firstName ) . ' ' . stripslashes( $attendee->lastName );

				if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SUFFIX ) == 'Y' ) && ( $attendee->suffix != '' ) ) {
					$body .= ' ' . stripslashes( $attendee->suffix );
				}

				$body .= ', </p>';

				if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_TEXT ) != '' ) {
					$content  = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_TEXT );
					$key_name = rsvp_pro_get_event_name( $rsvp_id ) . ' - ' . rsvp_pro_get_admin_string( 'settings_guest_eamil_text_label' );
					$content  = rsvp_pro_get_dynamic_translated_string( $key_name, $content, $rsvp_id );

					$body .= '<br />' . $content . '<br />';
				}

				$body .= rsvp_pro_retrieveEmailBodyContent( $attendee_id, $attendee );
				$body .= '</body></html>';
			}

			$headers = array( 'Content-Type: text/html; charset=UTF-8' );
			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) != '' ) {
				$headers[] = 'From: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
				$headers[] = 'Reply-To: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
				$headers[] = 'Return-Path: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
			}

			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_CC_ASSOCIATED ) == 'Y' ) &&
				 ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_ASSOCIATED_INDIVIDUALLY ) != 'Y' ) ) {
				$sql = 'SELECT email FROM ' . PRO_ATTENDEES_TABLE . ' a
	        		JOIN ' . PRO_ASSOCIATED_ATTENDEES_TABLE . " aa ON aa.attendeeID = a.id
	        		WHERE associatedAttendeeID = %d AND a.rsvpEventID = %d AND email != ''";
				$aa  = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $rsvp_id ) );
				if ( count( $aa ) > 0 ) {
					$ccEmails = '';
					foreach ( $aa as $a ) {
						$headers[] = 'Cc: ' . stripslashes( $a->email );
					}
				}
			}

			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_ASSOCIATED_INDIVIDUALLY ) == 'Y' ) &&
				 ! $associated_attendee ) {
				$sql = 'SELECT id FROM ' . PRO_ATTENDEES_TABLE . ' a
                    JOIN ' . PRO_ASSOCIATED_ATTENDEES_TABLE . " aa ON aa.attendeeID = a.id
                    WHERE associatedAttendeeID = %d AND a.rsvpEventID = %d AND email != ''";
				$aa  = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $rsvp_id ) );
				if ( count( $aa ) > 0 ) {
					foreach ( $aa as $a ) {
						rsvp_pro_frontend_handle_email_notifications( $a->id, $rsvp_id, true );
					}
				}
			}

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_BCC_ADDRESS ) != '' ) {
				$bccs = explode( ';', rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_BCC_ADDRESS ) );
				foreach ( $bccs as $bcc ) {
					$headers[] = 'Bcc: ' . trim( $bcc );
				}
			}
			$headers = apply_filters( 'rsvp_pro_attendee_email_headers', $headers );

			$subject = rsvp_pro_get_frontend_string( 'rsvp_notification_subject' );
			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_SUBJECT ) != '' ) {
				$subject = stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_SUBJECT ) );
			}
			$subject = apply_filters( 'rsvp_pro_attendee_email_subject', $subject );

			$tmp_ics_file = null;
			$tmp_ics_path = null;
			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_INCLUDE_ICS ) === 'Y' ) &&
				( strtolower( $attendee->rsvpStatus ) != 'no' ) ) {
				$tmp_file_name = sys_get_temp_dir() . DIRECTORY_SEPARATOR . rsvp_pro_get_event_name( $rsvp_id ) . '_' . uniqid() . '.ics';
				$tmp_ics_file  = fopen( $tmp_file_name, 'w+' );
				fwrite( $tmp_ics_file, rsvp_pro_retrieve_calendar_invite_content( $rsvp_id ) );
				$tmp_file_info = stream_get_meta_data( $tmp_ics_file );
				$tmp_ics_path  = $tmp_file_info['uri'];
				$attachments[] = $tmp_file_info['uri'];

				// Get the sub-events calendar information...
				$sql       = 'SELECT id, eventName FROM ' . PRO_EVENT_TABLE . ' WHERE parentEventID = %d';
				$subevents = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id ) );
				foreach ( $subevents as $se ) {
					if ( does_user_have_access_to_event( $se->id, $attendee_id ) && ( rsvp_pro_get_event_option( $se->id, RSVP_PRO_OPTION_EMAIL_INCLUDE_ICS ) === 'Y' ) ) {
						$tmp_file_name = sys_get_temp_dir() . DIRECTORY_SEPARATOR . stripslashes( $se->eventName ) . '_' . uniqid() . '.ics';
						$tmp_ics_file  = fopen( $tmp_file_name, 'w+' );
						fwrite( $tmp_ics_file, rsvp_pro_retrieve_calendar_invite_content( $se->id ) );
						$tmp_file_info = stream_get_meta_data( $tmp_ics_file );
						$tmp_ics_path  = $tmp_file_info['uri'];
						$attachments[] = $tmp_file_info['uri'];
					}
				}
			}
			$attachments = apply_filters( 'rsvp_pro_attendee_email_attachments', $attachments );

			$body = nl2br( $body );
			$body = apply_filters( 'rsvp_pro_attendee_email_body', $body );

			rsvp_pro_send_mail( $attendee->email, $subject, $body, $headers, $attachments );

			if ( $tmp_ics_file !== null ) {
				fclose( $tmp_ics_file );
				unlink( $tmp_ics_path );
			}
		}
	}
}

function rsvp_pro_set_yes_unavailable( $rsvpEventId ) {
	global $wpdb;
	$sql     = 'SELECT eventName, open_date, close_date, options, parentEventID, event_access
              FROM ' . PRO_EVENT_TABLE . ' WHERE id = %d';
	$event   = $wpdb->get_row( $wpdb->prepare( $sql, $rsvpEventId ) );
	$options = json_decode( $event->options, true );

	$options[ RSVP_PRO_OPTION_WAITLIST_YES_UNAVAILABLE ] = 'Y';

	$json_options = json_encode( $options );
	$wpdb->update(
		PRO_EVENT_TABLE,
		array( 'options' => $json_options ),
		array( 'id' => $rsvpEventId ),
		array( '%s' ),
		array( '%d' )
	);
}

/**
 * Sends the notification to the attendee that they have been moved from waitlist to "yes"
 *
 * @param int $event_id - The event we are changing the status for.
 * @param int $attendee_id - The attendnee we are changing the status for.
 */
function rsvp_pro_send_waitlist_status_change_notification( $event_id, $attendee_id ) {
	global $wpdb;
	global $rsvp_id;

	$function = 'rsvp_pro_get_event_option';
	if ( rsvp_pro_is_sub_event( $event_id ) ) {
		$function = 'rsvp_pro_get_sub_event_option';
	}

	$emailText = $function( $event_id, RSVP_PRO_OPTION_WAITLIST_STATUS_CHANGE_EMAIL );
	$emailText = trim( $emailText );
	if ( empty( $emailText ) ) {
		// Use the default text...
		$emailText = sprintf( rsvp_pro_get_frontend_string( 'rsvp_waitlist_notification_body' ), rsvp_pro_get_event_name( $event_id ) );
	} else {
		$sql = 'SELECT firstName, lastName, email, IFNULL(se.rsvpStatus, a.rsvpStatus) as rsvpStatus, 
                    passcode, salutation, suffix, note, a.id, a.token
  			       FROM ' . PRO_ATTENDEES_TABLE . ' a 
                   LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " se ON se.rsvpAttendeeID = a.id AND se.rsvpEventID = %d 
                   WHERE a.id= %d AND email != '' AND ( (a.rsvpEventID = %d)";

		if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
			$sql .= ' OR ( a.rsvpEventID = ' . RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID . ' ) ';
		}

		$sql        .= ')';
		$attendee    = $wpdb->get_row( $wpdb->prepare( $sql, $event_id, $attendee_id, $event_id ) );
		$attachments = array();
		$event_url   = rsvp_pro_get_event_permalink( $event_id );
		$emailText   = rsvp_pro_admin_replaceVariablesForEmail( $attendee, $event_url, $emailText, $event_id, $attachments );
	}

	// Get the person's email...
	$email = $wpdb->get_var( $wpdb->prepare( 'SELECT email FROM ' . PRO_ATTENDEES_TABLE . ' WHERE id = %d', $attendee_id ) );
	if ( ! empty( $email ) ) {
		$headers = array( 'Content-Type: text/html; charset=UTF-8' );
		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) != '' ) {
			$headers[] = 'From: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
			$headers[] = 'Reply-To: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
			$headers[] = 'Return-Path: ' . stripslashes( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_FROM ) ) . "\r\n";
		}

		rsvp_pro_send_mail( $email, rsvp_pro_get_frontend_string( 'rsvp_waitlist_notification_subject' ) . rsvp_pro_get_event_name( $event_id ), nl2br( $emailText ), $headers );
	}
}

/**
 * Checks to see if the RSVP event passed in is open for RSVP'ing or not.
 *
 * @param  int $rsvp_id The RSVP ID we want to know if it is open.
 *
 * @return boolean          true if it is open, false otherwise.
 */
function rsvp_pro_is_event_open( $rsvp_id ) {
	$open_date = rsvp_pro_get_event_information( $rsvp_id, RSVP_PRO_INFO_OPEN_DATE );
	$open_time = rsvp_pro_get_event_information( $rsvp_id, RSVP_PRO_INFO_OPEN_DATE_TIME );

	$time_zone = new DateTimeZone( rsvp_pro_wp_get_timezone_string() );

	$current_time = new DateTime();
	$current_time->setTimezone( $time_zone );

	$tmp_date_string = '';
	if ( strtotime( $open_date ) !== false ) {
		$tmp_date_string = $open_date;

		if ( ! empty( $open_time ) ) {
			$tmp_date_string .= ' ' . date( 'g:i a', strtotime( $open_time ) );
		}
	}

	$tmp_date          = new DateTime( $tmp_date_string, $time_zone );
	$current_timestamp = current_time( 'timestamp' );
	if ( method_exists( $tmp_date, 'getTimestamp' ) ) {
		$tmp_timestamp = $tmp_date->getTimestamp() + $tmp_date->getOffset();
	} else {
		$tmp_timestamp = $tmp_date->format( 'U' ) + $tmp_date->getOffset();
	}

	if ( ( strtotime( $open_date ) === false ) || ( $tmp_timestamp <= $current_timestamp ) ) {
		return true;
	}

	return false;
}

/**
 * Checks to see if the RSVP event passed in is closed for RSVP'ing or not.
 *
 * @param  int $rsvp_id The RSVP ID we want to know if it is closed.
 *
 * @return boolean          true if it is closed, false otherwise.
 */
function rsvp_pro_is_event_closed( $rsvp_id ) {
	$close_date = rsvp_pro_get_event_information( $rsvp_id, RSVP_PRO_INFO_CLOSE_DATE );
	$close_time = rsvp_pro_get_event_information( $rsvp_id, RSVP_PRO_INFO_CLOSE_DATE_TIME );

	$time_zone = new DateTimeZone( rsvp_pro_wp_get_timezone_string() );

	$tmp_date_string = '';
	if ( strtotime( $close_date ) !== false ) {
		$tmp_date_string = $close_date;

		if ( ! empty( $close_time ) ) {
			$tmp_date_string .= ' ' . $close_time;
		}
	}
	$tmp_date = new DateTime( $tmp_date_string, $time_zone );

	$current_timestamp = current_time( 'timestamp' );

	if ( method_exists( $tmp_date, 'getTimestamp' ) ) {
		$tmp_timestamp = $tmp_date->getTimestamp() + $tmp_date->getOffset();
	} else {
		$tmp_timestamp = $tmp_date->format( 'U' ) + $tmp_date->getOffset();
	}

	if ( ( strtotime( $close_date ) !== false ) && ( $tmp_timestamp <= $current_timestamp ) ) {
		return true;
	}

	return false;
}

/**
 * Uses the timezone information from the WordPress setup to correctly translate
 * the date pased in.
 *
 * @param  string $date_in A date string we need to get the timestamp for
 *
 * @return string          The date for the calendar with the timezone correctly set
 */
function rsvp_pro_get_timezone_set_date_for_calendar( $date_in ) {
	$time_zone = new DateTimeZone( rsvp_pro_wp_get_timezone_string() );

	$tmp_date_string = '';
	if ( strtotime( $date_in ) !== false ) {
		$tmp_date_string = $date_in;
	}
	$tmp_date = new DateTime( $tmp_date_string, new DateTimeZone( 'UTC' ) );

	if ( method_exists( $tmp_date, 'getTimestamp' ) ) {
		$tmp_timestamp = $tmp_date->getTimestamp();
	} else {
		$tmp_timestamp = $tmp_date->format( 'U' );
	}

	// This specifies that the time should be in UTC format
	return date( 'Ymd\THis\Z', $tmp_timestamp );
}

/**
 * Returns the timezone string for a site, even if it's set to a UTC offset
 *
 * Adapted from http://www.php.net/manual/en/function.timezone-name-from-abbr.php#89155
 * Taken from https://www.skyverge.com/blog/down-the-rabbit-hole-wordpress-and-timezones/
 *
 * @return string valid PHP timezone string
 */
function rsvp_pro_wp_get_timezone_string() {

	// if site timezone string exists, return it
	if ( $timezone = get_option( 'timezone_string' ) ) {
		return $timezone;
	}

	// get UTC offset, if it isn't set then return UTC
	if ( 0 === ( $utc_offset = get_option( 'gmt_offset', 0 ) ) ) {
		return 'UTC';
	}

	// adjust UTC offset from hours to seconds
	$utc_offset *= 3600;

	// attempt to guess the timezone string from the UTC offset
	if ( $timezone = timezone_name_from_abbr( '', $utc_offset, 0 ) ) {
		return $timezone;
	}

	// last try, guess timezone string manually
	$is_dst = date_i18n( 'I' );

	foreach ( timezone_abbreviations_list() as $abbr ) {
		foreach ( $abbr as $city ) {
			if ( $city['dst'] == $is_dst && $city['offset'] == $utc_offset ) {
				return $city['timezone_id'];
			}
		}
	}

	// fallback to UTC
	return 'UTC';
}

/**
 * Gets the start of the RSVP pro front-end container.
 *
 * @return string The HTML that will be used for the beginning of the front-end container
 */
function rsvp_pro_get_beginning_of_frontend_container() {
	global $rsvp_id;

	$output = "<div id=\"rsvpPlugin\">\r\n";

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_EVENT_INFO_ON_FRONTEND ) === 'Y' ) {
		$output .= "<div id=\"rsvpProEventDescription\">\r\n";
		$output .= RSVP_PRO_START_PARA . rsvp_pro_get_event_information( $rsvp_id, RSVP_PRO_INFO_DESCRIPTION ) . RSVP_PRO_END_PARA;
		$output .= "</div>\r\n";
	}

	return $output;
}

/**
 * Gets the yes verbiage for the main RSVP question. Will check to see if the
 * custom verbiage is filled out and if not will use the default text.
 *
 * @param  int $rsvp_id The rsvp ID we want to get the customized text for.
 *
 * @return string          The yes verbiage that should be used on the form.
 */
function rsvp_pro_get_yes_verbiage( $rsvp_id ) {
	$yes_text = rsvp_pro_get_frontend_string( 'rsvp_yes_label' );

	if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_YES_VERBIAGE ) ) !== '' ) {
		$yes_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_YES_VERBIAGE );
	}

	return $yes_text;
}

/**
 * Gets the "no" verbiage for the main RSVP question. Will check to see if the
 * custom verbiage is filled out and if not will use the default text.
 *
 * @param  int $rsvp_id The event ID we want to get the customized text for.
 *
 * @return string          The "no" verbiage that should be used on the form.
 */
function rsvp_pro_get_no_verbiage( $rsvp_id ) {
	$no_text = rsvp_pro_get_frontend_string( 'rsvp_no_label' );

	if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_VERBIAGE ) ) !== '' ) {
		$no_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NO_VERBIAGE );
	}

	return $no_text;
}

/**
 * Get the "waitlist" verbiage for the main RSVP question. Will check for
 * customized text and if not set will use the default text.
 *
 * @param  int $rsvp_id The event ID we want to get the customized text for.
 *
 * @return string          The text to use for the "waitlist" verbiage.
 */
function rsvp_pro_get_waitlist_verbiage( $rsvp_id ) {
	$waitlist_text = rsvp_pro_get_frontend_string( 'rsvp_waitlist_label' );

	if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WAITLIST_VERBIAGE ) ) !== '' ) {
		$waitlist_text = trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_WAITLIST_VERBIAGE ) );
	}

	return $waitlist_text;
}

/**
 * Get the "maybe" verbiage for the main RSVP question.
 *
 * @param  int $rsvp_id The event ID we want to get the customized text for
 *
 * @return string          The text to use for the "maybe" verbiage
 */
function rsvp_pro_get_maybe_verbiage( $rsvp_id ) {
	$maybe_text = rsvp_pro_get_frontend_string( 'rsvp_maybe_label' );

	if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MAYBE_VERBIAGE ) ) !== '' ) {
		$maybe_text = trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_MAYBE_VERBIAGE ) );
	}

	return $maybe_text;
}

/**
 * Get the "Yes, plus one" verbiage for the main RSVP question.
 *
 * @param  int $rsvp_id The event ID we want to get the customized text for
 *
 * @return string          The text to use for the "maybe" verbiage
 */
function rsvp_pro_get_plus_one_verbiage( $rsvp_id ) {
	$plus_one_text = rsvp_pro_get_frontend_string( 'plus_one_label' );

	if ( trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PLUS_ONE_LABEL ) ) !== '' ) {
		$plus_one_text = trim( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PLUS_ONE_LABEL ) );
	}

	return $plus_one_text;
}

/**
 * Returns the HTML for the register a new attendee button
 *
 * @return string          The HTML for the new attendee registration button
 */
function rsvp_pro_frontend_new_attendee_button() {
	global $rsvp_hide_new_form;
	global $rsvp_form_action;
	global $rsvp_id;

	$output = '';

	$not_found_message_text = rsvp_pro_get_frontend_string( 'not_found_add_yourself_message' );
	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PROMPT_TO_ADD_IF_NOT_FOUND_TEXT ) !== '' ) {
		$not_found_message_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PROMPT_TO_ADD_IF_NOT_FOUND_TEXT );
	}

	if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PROMPT_TO_ADD_IF_NOT_FOUND ) === 'Y' ) &&
		 ! $rsvp_hide_new_form ) {
		$output .= RSVP_PRO_START_PARA . $not_found_message_text . RSVP_PRO_END_PARA;
	}

	$button_text = rsvp_pro_get_frontend_string( 'new_attendee_button' );

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NEW_ATTENDEE_BUTTON_TEXT ) != '' ) {
		$button_text = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NEW_ATTENDEE_BUTTON_TEXT );
	}
	$output .= '<div id="rsvp_new_attendee_form">';
	$output .= "<form name=\"rsvpNew\" method=\"post\" id=\"rsvpNew\" action=\"$rsvp_form_action\">\r\n";
	$output .= '  <input type="hidden" name="rsvp_id" id="rsvp_id" value="' . $rsvp_id . '" />';
	$output .= '    <input type="hidden" name="rsvpStep' . $rsvp_id . '" value="newattendee" />';
	$output .= "<input type=\"submit\" value=\"$button_text\" class=\"rsvpSubmit\" />\r\n";
	$output .= "</form>\r\n";
	$output .= "</div>\r\n";

	return $output;
}

/**
 * AJAX handler to get the JavaScript validation messages.
 *
 * @return array A Json encoded array of the JavaScript validation messages.
 */
function rsvp_pro_ajax_get_validation_messages() {
	if ( isset( $_POST['rsvp_id'] ) && ( $_POST['rsvp_id'] > 0 ) ) {
		$data = rsvp_pro_get_validation_messages( $_POST['rsvp_id'] );
		echo json_encode( $data );
	}

	die();
}

/**
 * AJAX handler for the RSVP form submissions when the "no refresh" option is enabled.
 *
 * @return string The next HTML form and/or page that should be displayed.
 */
function rsvp_pro_ajax_handle_rsvp_form() {
	global $rsvp_inside_ajax_request;

	if ( isset( $_POST['rsvp_id'] ) && ( $_POST['rsvp_id'] > 0 ) ) {
		$rsvp_inside_ajax_request = true;
		$atts                     = array( 'id' => $_POST['rsvp_id'] );
		$output                   = rsvp_pro_shortcode_handler( $atts );
		echo $output;
		exit;
	}
}

/**
 * Gets the JavaScript validation messages for the RSVP Pro plugin.
 *
 * @param  int $rsvp_id The event we want to get the messages for.
 *
 * @return array          An array of all the JavaScript validation messages.
 */
function rsvp_pro_get_validation_messages( $rsvp_id ) {
	global $wpdb;

	$first_name_message      = rsvp_pro_get_frontend_string( 'javascript_first_name_validation' );
	$last_name_message       = rsvp_pro_get_frontend_string( 'javascript_last_name_validation' );
	$note_message            = rsvp_pro_get_frontend_string( 'javascript_note_validation' );
	$email_message           = rsvp_pro_get_frontend_string( 'javascript_email_validation' );
	$gdpr_message            = rsvp_pro_get_frontend_string( 'javascript_gdpr_validation' );
	$unique_passcode_message = rsvp_pro_get_frontend_string( 'javascript_unique_passcode_validation' );
	$unique_email_message    = rsvp_pro_get_frontend_string( 'javascript_unique_email_validation' );
	$require_unique_passcode = false;
	$require_unique_email    = false;
	$require_last_name       = true;
	$enable_ajax             = false;
	$always_show_additional  = false;
	$enable_payments         = false;
	$ticket_prices           = array();
	$thousands_separator     = ',';
	$decimal_separator       = '.';
	$currency_symbol         = '$';
	$currency_position       = 'before';

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_NAME_JS_MESSAGE ) !== '' ) {
		$first_name_message = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_NAME_JS_MESSAGE );
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_JS_MESSAGE ) !== '' ) {
		$last_name_message = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_JS_MESSAGE );
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOTE_JS_MESSAGE ) !== '' ) {
		$note_message = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOTE_JS_MESSAGE );
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_JS_MESSAGE ) !== '' ) {
		$email_message = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_JS_MESSAGE );
	}

	if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_JS_MESSAGE ) ) {
		$gdpr_message = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_GDPR_JS_MESSAGE );
	}

	if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_UNIQUE_PASSCODE_JS_MESSAGE ) ) {
		$unique_passcode_message = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_UNIQUE_PASSCODE_JS_MESSAGE );
	}

	if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_NOT_REQUIRED ) === 'Y' ) {
		$require_last_name = false;
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_EMAIL_UNIQUE_VALIDATION ) ) {
		$require_unique_email = true;
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_UNIQUE ) ) {
		$require_unique_passcode = true;
	}

	if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_UNIQUE_EMAIL_JS_MESSAGE ) ) {
		$unique_email_message = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_UNIQUE_EMAIL_JS_MESSAGE );
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_AJAX ) ) {
		$enable_ajax = true;
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ALWAYS_SHOW_ADDITIONAL ) ) {
		$always_show_additional = true;
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_PAYMENTS ) ) {
		$enable_payments = true;
	}

	if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THOUSANDS_SEPARATOR ) ) {
		$thousands_separator = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THOUSANDS_SEPARATOR );
	}

	if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DECIMAL_SEPARATOR ) ) {
		$decimal_separator = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_DECIMAL_SEPARATOR );
	}

	if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CURRENCY ) ) {
		$currency_symbol = rsvp_pro_get_currency_symbol( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CURRENCY ) );
	}

	if ( '' !== rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CURRENCY_POSITION ) ) {
		$currency_position = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_CURRENCY_POSITION );
	}

	$ticket_prices['main'] = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_TICKET_PRICE );
	$sql                   = 'SELECT id FROM ' . PRO_EVENT_TABLE . ' WHERE parentEventID = %d';
	$subevents             = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_id ) );
	foreach ( $subevents as $se ) {
		$ticket_prices[$se->id] = rsvp_pro_get_event_option( $se->id, RSVP_PRO_OPTION_TICKET_PRICE );
	}

	$data = array(
		'first_name_message'      => $first_name_message,
		'last_name_message'       => $last_name_message,
		'note_message'            => $note_message,
		'email_message'           => $email_message,
		'require_last_name'       => $require_last_name,
		'gdpr_message'            => $gdpr_message,
		'unique_passcode_message' => $unique_passcode_message,
		'ajaxurl'                 => admin_url( 'admin-ajax.php' ),
		'require_unique_passcode' => $require_unique_passcode,
		'require_unique_email'    => $require_unique_email,
		'unique_email_message'    => $unique_email_message,
		'enable_ajax'             => $enable_ajax,
		'always_show_additional'  => $always_show_additional,
		'enable_payments'         => $enable_payments,
		'thousands_separator'     => $thousands_separator,
		'decimal_separator'       => $decimal_separator,
		'currency_symbol'         => $currency_symbol,
		'ticket_prices'           => $ticket_prices,
		'currency_position'       => $currency_position,
	);

	return $data;
}

/**
 * Loads the frontend JavaScript variables.
 */
function rsvp_pro_load_frontend_javascript_variables() {
	global $rsvp_id;

	$data = rsvp_pro_get_validation_messages( $rsvp_id );

	wp_localize_script( 'rsvp_pro_plugin', 'rsvp_pro_data', $data );
}

/**
 * Handler for a special querystring variable for checking in an attendee.
 */
function rsvp_pro_attendee_checkin_listener() {
	global $wpdb;
	if ( isset( $_GET ) && isset( $_GET['rsvp_pro_attendee'] ) && ( '' !== $_GET['rsvp_pro_attendee'] ) ) {
		$tmp_token = wp_unslash( $_GET['rsvp_pro_attendee'] );
		$sql       = 'SELECT a.id, firstName, lastName, a.token, se.token AS subToken, IFNULL(se.checked_in, a.checked_in) AS checked_in FROM ' . PRO_ATTENDEES_TABLE . ' a 
		LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpAttendeeID = a.id 
		WHERE a.token = %s OR se.token = %s ';

		$tokens    = $wpdb->get_row( $wpdb->prepare( $sql, $tmp_token, $tmp_token ) );
		$html      = '<div class="rsvp_attendee_checking_response_wrap %s"><p class="rsvp_attendee_checking_response_message"> %s </p></div>';
		$response = false;

		if ( null !== $tokens ) {
			if ( 'Y' === $tokens->checked_in ) {
				$response = __( 'Attendee is already checked in.', 'rsvp-pro-plugin' );
			} else {
				if ( strtolower( $tokens->token ) == strtolower( $tmp_token ) ) {
					$wpdb->update(
						PRO_ATTENDEES_TABLE,
						array(
							'checked_in' => 'Y',
						),
						array(
							'token' => $tmp_token,
						),
						array( '%s' ),
						array( '%s' )
					);
				} else {
					$wpdb->update(
						PRO_ATTENDEE_SUB_EVENTS_TABLE,
						array(
							'checked_in' => 'Y',
						),
						array(
							'token' => $tmp_token,
						),
						array( '%s' ),
						array( '%s' )
					);
				}

				$response = __( 'Attendee checked in.', 'rsvp-pro-plugin' );
			}
		} else {
			$response = __( 'Unable to find attendee!', 'rsvp-pro-plugin' );
		}

		echo wp_kses_post( apply_filters( 'rsvp_attendee_checking_response', sprintf( $html, ( null !== $tokens ) ? 'rsvp_success' : 'rsvp_failed', esc_html( $response ) ), $tokens ) );
		exit;
	}
}
