<?php
/**
 * Include that handles all of the RSVP'ing for a given set of attendees
 *
 * @since 2.1.3
 * @package  rsvp-pro-plugin
 */

/**
 * Handles RSVP'ing for attendees.
 *
 * @param  string $output The output we want to return to the client.
 * @param  string $text The current text on the page.
 * @param  bool   $skip_nonce_check Skips the nonce check we use this if we are programmatically calling this function.
 */
function rsvp_pro_handlersvp( &$output, &$text, $skip_nonce_check = false ) {
	global $wpdb;
	global $rsvp_id;
	global $rsvp_pro_saved_form_vars;
	global $rsvp_inside_ajax_request;
	$thank_you_primary    = '';
	$thank_you_associated = array();
	$main_rsvp_status     = '';
	$is_new_attendee      = rsvp_pro_is_rsvp_new_attendee();

	foreach ( $_POST as $key => $val ) {
		$rsvp_pro_saved_form_vars[ $key ] = $val;
	}

	if ( ! $skip_nonce_check && ( ! isset( $_POST['rsvp_nonce_name'] ) || ! isset( $_POST['rsvp_nonce_value'] ) ||
								  ! WPSimpleNonce::checkNonce( $_POST['rsvp_nonce_name'], $_POST['rsvp_nonce_value'] ) )
	) {
		return rsvp_pro_handle_output( $text, rsvp_pro_frontend_greeting() );
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_RECAPTCHA ) &&
		 ( ! isset( $_POST['g-recaptcha-response'] ) || ! rsvp_pro_validate_recaptcha( $_POST['g-recaptcha-response'] ) ) ) {
		$tmp_attendee_id = 0;
		if ( ! $is_new_attendee ) {
			$tmp_attendee_id = $_POST['attendeeID'];
		}
		$rsvp_pro_saved_form_vars['captcha_validation_message'] = rsvp_pro_get_frontend_string( 'captcha_validation_message' );
		return rsvp_pro_handle_output( $text, rsvp_pro_frontend_main_form( $tmp_attendee_id ) );
	}

	if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_TURNSTILE ) &&
		 ( ! isset( $_POST['cf-turnstile-response'] ) || ! rsvp_pro_validate_turnstile( $_POST['cf-turnstile-response'] ) ) ) {
		$tmp_attendee_id = 0;
		if ( ! $is_new_attendee ) {
			$tmp_attendee_id = $_POST['attendeeID'];
		}
		$rsvp_pro_saved_form_vars['captcha_validation_message'] = rsvp_pro_get_frontend_string( 'captcha_validation_message' );
		return rsvp_pro_handle_output( $text, rsvp_pro_frontend_main_form( $tmp_attendee_id ) );
	}

	if ( isset( $_POST['attendeeFirstName'] ) && isset( $_POST['attendeeLastName'] ) &&
		 ( empty( $_POST['attendeeFirstName'] ) ||
		   ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_NOT_REQUIRED ) !== 'Y' ) && empty( $_POST['attendeeLastName'] ) ) ) ) {
		if ( $is_new_attendee ) {
			return rsvp_pro_handlenewattendee( $output, $text );
		} else {
			return rsvp_pro_editAttendee( $output, $text );
		}
	}

	$attendee = new Rsvp_Pro_Attendee();
	if ( $is_new_attendee ) {
		if ( rsvp_pro_frontend_max_limit_for_all_events() ) {
			return rsvp_pro_handle_max_limit_reached_message( $rsvp_id );
		}

		$attendee->set_first_name( $_POST['attendeeFirstName'] );
		$attendee->set_last_name( $_POST['attendeeLastName'] );
		$attendee->set_rsvp_date( date( 'Y-m-d H:i:s' ) );
		$attendee->set_rsvp_event_id( $rsvp_id );
		$attendee->save();
	} else {
		$attendee = new Rsvp_Pro_Attendee( $_POST['attendeeID'] );
	}

	if ( $attendee->get_id() > 0 ) {
		rsvp_pro_save_attendee_changelog( $rsvp_id, $attendee->get_id(), 'main', 'mainquestion', 'main' );
		$thank_you_primary = $attendee->get_first_name();

		if ( isset( $_POST['mainRsvp'] ) ) {
			// update their information and what not.
			$rsvp_status = rsvp_pro_translate_form_value_to_status( $_POST['mainRsvp'] );

			if ( rsvp_pro_frontend_max_limit_hit( $rsvp_id ) ) {
				if ( ( ( $attendee->rsvpStatus != 'Yes' ) || ( $attendee->rsvpStatus != 'PlusOne' ) ) && ( $rsvp_status == 'Yes' ) ) {
					$rsvp_status = 'No';
				}
			}
			$main_rsvp_status = $rsvp_status;

			if ( rsvp_pro_is_shared_attendee_list_enabled() && ( $attendee->get_rsvp_event_id() == RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID ) ) {
				$sub_event = new Rsvp_Pro_Attendee_Subevent();

				foreach ( $attendee->get_sub_event_responses() as $se ) {
					if ( $se->get_event_id() === $rsvp_id ) {
						$sub_event = $se;
						break;
					}
				}

				$sub_event->set_rsvp_status( $rsvp_status );
				$sub_event->set_rsvp_date( date( 'Y-m-d H:i:s' ) );
				if ( $sub_event->get_id() <= 0 ) {
					$sub_event->set_event_id( $rsvp_id );
					$sub_event->set_attendee_id( $attendee->get_id() );
				}
				$attendee->add_sub_event_responses( $sub_event );
				$attendee->set_note( ( isset( $_POST['rsvp_note'] ) ? $_POST['rsvp_note'] : '' ) );
			} else {
				$attendee->set_rsvp_date( date( 'Y-m-d H:i:s' ) );
				$attendee->set_rsvp_status( $rsvp_status );
				$attendee->set_note( ( isset( $_POST['rsvp_note'] ) ? $_POST['rsvp_note'] : '' ) );
			}
		}

		if ( isset( $_POST['mainEmail'] ) && ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_HIDE_EMAIL_FIELD ) != 'Y' ) ||
											   ( $is_new_attendee && ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ATTENDEE_LOOKUP_VIA_EMAIL ) === 'Y' ) ) ) ) {
			$attendee->set_email( $_POST['mainEmail'] );
		}

		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_LAST_EDITABLE ) === 'Y' ) {
			$attendee->set_first_name( $_POST['attendeeFirstName'] );
			$attendee->set_last_name( $_POST['attendeeLastName'] );
		}

		rsvp_pro_add_passcode_if_needed( $attendee, 'attendeePasscode' );
		rsvp_pro_handleSuffixAndSalutation( $attendee, 'main' );
		rsvp_pro_handleSubEvents( $attendee, 'main' );
		$attendee->save();

		rsvp_pro_handleAdditionalQuestions( $attendee->get_id(), 'mainquestion' );

		$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) 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->get_id(), $attendee->get_id(), $attendee->get_id(), $attendee->get_id(), $rsvp_id ) );
		foreach ( $associations as $a ) {
			if ( $a->id > 0 ) {
				$aid                 = $a->id;
				$associated_attendee = new Rsvp_Pro_Attendee( $aid );

				rsvp_pro_save_attendee_changelog( $rsvp_id, $aid, 'attending' . $aid, $aid . 'question', $aid . 'Existing' );

				if ( isset( $_POST[ 'attending' . $aid ] ) &&
					 ( ( $_POST[ 'attending' . $aid ] === 'Y' ) || ( $_POST[ 'attending' . $aid ] === 'N' ) || ( $_POST[ 'attending' . $aid ] === 'NoResponse' ) || ( $_POST[ 'attending' . $aid ] === 'M' ) ) ) {
					if ( $_POST[ 'attending' . $aid ] !== 'NoResponse' ) {
						$thank_you_associated[] = $associated_attendee->get_first_name();
					}

					$rsvp_status = rsvp_pro_translate_form_value_to_status( $_POST[ 'attending' . $aid ] );

					if ( rsvp_pro_frontend_max_limit_hit( $rsvp_id ) ) {
						if ( ( $attendee->get_rsvp_status() !== 'Yes' ) && ( $rsvp_status === 'Yes' ) ) {
							$rsvp_status = 'No';
						}
					}
					if ( rsvp_pro_is_shared_attendee_list_enabled() && ( $associated_attendee->get_rsvp_event_id() == RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID ) ) {
						$subevent = new Rsvp_Pro_Attendee_Subevent();
						$subevent->set_attendee_id( $aid );
						foreach ( $associated_attendee->get_sub_event_responses() as $ser ) {
							if ( $ser->get_event_id() === $rsvp_id ) {
								$subevent = $ser;
							}
						}

						$subevent->set_rsvp_status( trim( $rsvp_status ) );
						$subevent->set_rsvp_date( date( 'Y-m-d H:i:s' ) );
						$subevent->set_event_id( $rsvp_id );
						$associated_attendee->add_sub_event_responses( $subevent );
					} else {
						$associated_attendee->set_rsvp_status( $rsvp_status );
						$associated_attendee->set_rsvp_date( date( 'Y-m-d H:i:s' ) );
					}
				}
			}

			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_HIDE_EMAIL_FIELD ) !== 'Y' ) && isset( $_POST[ 'attending' . $aid . 'Email' ] ) ) {
				$associated_attendee->set_email( $_POST[ 'attending' . $aid . 'Email' ] );
			}

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_LAST_EDITABLE ) === 'Y' ) {
				$associated_attendee->set_first_name( $_POST[ 'attending' . $aid . 'FirstName' ] );
				$associated_attendee->set_last_name( $_POST[ 'attending' . $aid . 'LastName' ] );
			}

			rsvp_pro_add_passcode_if_needed( $associated_attendee, 'attending' . $aid . 'Passcode' );
			rsvp_pro_handleSuffixAndSalutation( $associated_attendee, 'attending' . $aid );
			rsvp_pro_handleSubEvents( $associated_attendee, $aid . 'Existing' );
			$associated_attendee->save();

			rsvp_pro_handleAdditionalQuestions( $associated_attendee->get_id(), $associated_attendee->get_id() . 'question' );
		}

		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_HIDE_ADDITIONAL ) !== 'Y' ) {
			$num_guests = get_number_additional( $rsvp_id, $attendee );
			if ( isset( $_POST['additionalRsvp'] ) &&
				 is_numeric( $_POST['additionalRsvp'] ) &&
				 ( $_POST['additionalRsvp'] > 0 ) &&
				 isset( $_POST['additionalRsvpIds'] ) &&
				 ! empty( $_POST['additionalRsvpIds'] ) ) {
				$additional_ids = explode( ',', $_POST['additionalRsvpIds'] );

				foreach ( $additional_ids as $aid ) {
					if ( ! empty( $_POST[ 'newAttending' . $aid . 'FirstName' ] ) &&
						 ( ! empty( $_POST[ 'newAttending' . $aid . 'LastName' ] ) || ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_LAST_NAME_NOT_REQUIRED ) === 'Y' ) ) ) {

						$rsvp_status = rsvp_pro_translate_form_value_to_status( $_POST[ 'newAttending' . $aid ] );

						if ( rsvp_pro_frontend_max_limit_hit( $rsvp_id ) && ( $rsvp_status === 'Yes' ) ) {
							$rsvp_status = 'No';
						}

						if ( $rsvp_status != 'NoResponse' ) {
							$thank_you_associated[] = $_POST[ 'newAttending' . $aid . 'FirstName' ];
						}

						$new_attendee = new Rsvp_Pro_Attendee();
						$new_attendee->set_first_name( trim( $_POST[ 'newAttending' . $aid . 'FirstName' ] ) );
						$new_attendee->set_last_name( trim( $_POST[ 'newAttending' . $aid . 'LastName' ] ) );
						$new_attendee->set_email( trim( $_POST[ 'newAttending' . $aid . 'Email' ] ) );
						$new_attendee->set_additional_attendee( 'Y' );
						$new_attendee->set_rsvp_date( date( 'Y-m-d H:i:s' ) );
						$new_attendee->set_rsvp_status( $rsvp_status );
						$new_attendee->set_rsvp_event_id( $rsvp_id );
						$new_attendee->set_associated_attendees( array( $attendee->get_id() ) );

						rsvp_pro_add_passcode_if_needed( $new_attendee, 'newAttending' . $aid . 'Passcode' );
						rsvp_pro_handleSuffixAndSalutation( $new_attendee, 'newAttending' . $aid );
						rsvp_pro_handleSubEvents( $new_attendee, $aid );
						$new_attendee->save();

						rsvp_pro_copy_event_permissions( $new_attendee->get_id(), $attendee->get_id() );
						rsvp_pro_handleAdditionalQuestions( $new_attendee->get_id(), $aid . 'question' );
					}
				}
			}
		}

		rsvp_pro_handleGroupQuestions( $attendee->get_id() );
		rsvp_pro_auto_rsvp_attendees( $rsvp_id );
		rsvp_pro_frontend_handle_email_notifications( $attendee->get_id(), $rsvp_id );

		$yes_redirect = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_THANKYOU_REDIRECT );
		$no_redirect  = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_NOT_COMING_REDIRECT );

		if ( ( 'Yes' === $main_rsvp_status ) && ! empty( $yes_redirect ) ) {
			ob_clean();
			if ( $rsvp_inside_ajax_request === true ) {
				echo '<script type="text/javascript">';
				echo 'window.location="' . $yes_redirect . '";';
				echo '</script>';
			} else {
				wp_redirect( $yes_redirect );
			}
			exit;
		} elseif ( ( 'No' === $main_rsvp_status ) && ! empty( $no_redirect ) ) {
			ob_clean();
			if ( $rsvp_inside_ajax_request === true ) {
				echo '<script type="text/javascript">';
				echo 'window.location="' . $no_redirect . '";';
				echo '</script>';
			} else {
				wp_redirect( $no_redirect );
			}
			exit;
		}
		$confirmation_page_output = '';
		if ( $is_new_attendee ) {
			$confirmation_page_output = rsvp_pro_frontend_new_attendee_thankyou(
				$thank_you_primary,
				$thank_you_associated,
				$main_rsvp_status,
				$attendee->get_id(),
				$attendee->get_passcode()
			);
		} else {
			$confirmation_page_output = rsvp_pro_frontend_thankyou(
				$thank_you_primary,
				$thank_you_associated,
				$main_rsvp_status,
				$attendee->get_id()
			);
		}

		if ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_ENABLE_PAYMENTS ) ) {
			$confirmation_page_output = rsvp_pro_retrieve_payment_output( $rsvp_id, $attendee ) . $confirmation_page_output;
		}

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

/**
 * This function outputs the text and form information for paying for an event.
 *
 * @param  int     $event_id The main event ID we are trying to pay for.
 * @param  obbject $attendee An instance of Rsvp_Pro_Attendee.
 * @return string           The HTML to be displayed to show what needs to be paid for.
 */
function rsvp_pro_retrieve_payment_output( $event_id, $attendee ) {
	$total_due        = rsvp_pro_existing_attendee_calculate_total_due( $event_id, $attendee );
	$total_due        = $total_due['total'];
	$currency_code    = 'USD';
	$is_symbol_before = true;
	if ( '' !== rsvp_pro_get_event_option( $event_id, RSVP_PRO_OPTION_CURRENCY ) ) {
		$currency_code = rsvp_pro_get_event_option( $event_id, RSVP_PRO_OPTION_CURRENCY );
	}

	if ( 'after' === rsvp_pro_get_event_option( $event_id, RSVP_PRO_OPTION_CURRENCY_POSITION ) ) {
		$is_symbol_before = false;
	}

	$currency_symbol = rsvp_pro_get_currency_symbol( $currency_code );
	$payment_message = rsvp_pro_get_frontend_string( 'payment_message' );

	if ( $is_symbol_before ) {
		$total_due = $currency_symbol . $total_due;
	} else {
		$total_due .= $currency_symbol;
	}

	if ( '' !== rsvp_pro_get_event_option( $event_id, RSVP_PRO_OPTION_PAYMENT_MESSAGE ) ) {
		$payment_message = rsvp_pro_get_event_option( $event_id, RSVP_PRO_OPTION_PAYMENT_MESSAGE );
	}
	$payment_message = sprintf( $payment_message, $total_due );

	$output = '<p class="rsvpParagraph">' . esc_html( $payment_message ) . '</p>';
	$output = apply_filters( 'rsvp_pro_frontend_payment_form', $output, $event_id, $attendee->get_id() );
	return $output;
}

/**
 * Checks to see whether we are handling a new attendee or not.
 *
 * @return boolean | true if it is a new attendee, false otherwise
 */
function rsvp_pro_is_rsvp_new_attendee() {
	if ( is_numeric( $_POST['attendeeID'] ) && ( $_POST['attendeeID'] > 0 ) ) {
		return false;
	}

	return true;
}

/**
 * Add the passcode for the attendee.
 *
 * @param  Rsvp_Pro_Attendee $attendee The attendee object.
 * @param  string            $form_element_name The form element name that should have the passcode.
 */
function rsvp_pro_add_passcode_if_needed( &$attendee, $form_element_name ) {
	global $rsvp_id, $wpdb;

	if ( rsvp_pro_require_passcode( $rsvp_id ) && empty( $attendee->get_passcode() ) ) {
		$length = 6;

		if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSWORD_LENGTH ) > 0 ) {
			$length = rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSWORD_LENGTH );
		}
		$rsvp_password = trim( rsvp_pro_generate_passcode( $length ) );
		$attendee->set_passcode( $rsvp_password );
	}

	if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_EDITABLE ) === 'Y' ) &&
		 isset( $_POST[ $form_element_name ] ) ) {
		$attendee->set_passcode( $_POST[ $form_element_name ] );
	}
}

/**
 * Tries to update the salutation and suffix for the attendee.
 *
 * @param  Rsvp_Pro_Attendee $attendee The Rsvp Attendee object who should get the salutation and suffix updated.
 * @param  string            $form_prefix The form prefix for this attendee.
 */
function rsvp_pro_handleSuffixAndSalutation( &$attendee, $form_prefix ) {
	global $rsvp_id;
	global $wpdb;

	if ( ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SALUTATION ) ) && isset( $_POST[ $form_prefix . 'Salutation' ] ) ) {
		$attendee->set_salutation( $_POST[ $form_prefix . 'Salutation' ] );
	}

	if ( ( 'Y' === rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SUFFIX ) ) && isset( $_POST[ $form_prefix . 'Suffix' ] ) ) {
		$attendee->set_suffix( trim( $_POST[ $form_prefix . 'Suffix' ] ) );
	}
}

/**
 * Handles recording the sub-event information for a specific attendee.
 *
 * @param  RSVP_Pro_Attendee $attendee The RSVP Attendee object who should get the sub-event information associated with.
 * @param  string            $form_name The prefix for the form elements we want to save information for.
 */
function rsvp_pro_handleSubEvents( &$attendee, $form_name ) {
	global $wpdb;
	global $rsvp_id;

	$sql       = 'SELECT e.id, se.id AS attendeeRecId, 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 e.parentEventID = %d';
	$subevents = $wpdb->get_results( $wpdb->prepare( $sql, $attendee->get_id(), $rsvp_id ) );
	foreach ( $subevents as $se ) {
		if ( isset( $_POST[ $form_name . 'RsvpSub' . $se->id ] ) ) {
			$rsvp_status = rsvp_pro_translate_form_value_to_status( $_POST[ $form_name . 'RsvpSub' . $se->id ] );

			// Handle the case when the limit is hit but people want to RSVP as yes, don't allow it...
			if ( rsvp_pro_frontend_max_limit_hit( $se->id ) ) {
				if ( ( ( $se->rsvpStatus != 'Yes' ) || ( $se->rsvpStatus != 'PlusOne' ) ) && ( $rsvp_status == 'Yes' ) ) {
					$rsvp_status = 'No';
				}
			}
			$sub_event = new Rsvp_Pro_Attendee_Subevent();
			foreach ( $attendee->get_sub_event_responses() as $ase ) {
				if ( $ase->get_id() === $se->attendeeRecId ) {
					$sub_event = $ase;
					break;
				}
			}

			$sub_event->set_rsvp_status( $rsvp_status );
			$sub_event->set_rsvp_date( date( 'Y-m-d H:i:s' ) );
			$sub_event->set_event_id( $se->id );
			$sub_event->set_attendee_id( $attendee->get_id() );

			$attendee->add_sub_event_responses( $sub_event );
		}
	}
}

function rsvp_pro_handleAdditionalQuestions( $attendee_id, $form_name, $isAdmin = false ) {
	global $wpdb;
	global $rsvp_id;

	if ( $isAdmin ) {
		$wpdb->query(
			$wpdb->prepare(
				'DELETE FROM ' . PRO_ATTENDEE_ANSWERS . ' WHERE attendeeID = %d AND
        				questionID IN (SELECT q.id FROM ' . PRO_QUESTIONS_TABLE . ' q
                       INNER JOIN ' . PRO_EVENT_TABLE . ' e ON e.id = q.rsvpEventID
                       INNER JOIN ' . PRO_QUESTION_TYPE_TABLE . " qt ON qt.id = q.questionTypeID
                       WHERE (e.id = $rsvp_id OR e.parentEventID = $rsvp_id) AND
                         qt.questionType NOT IN ('file') AND
                    	(IFNULL(e.event_access, '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "') != '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "' OR (%d IN (SELECT rsvpAttendeeID FROM " . PRO_EVENT_ATTENDEE_TABLE . ' WHERE rsvpEventID = e.id)))) ',
				$attendee_id,
				$attendee_id
			)
		);
	} else {
		$wpdb->query(
			$wpdb->prepare(
				'DELETE FROM ' . PRO_ATTENDEE_ANSWERS . ' WHERE attendeeID = %d AND
        			questionID IN (SELECT q.id FROM ' . PRO_QUESTIONS_TABLE . ' q
                       INNER JOIN ' . PRO_EVENT_TABLE . ' e ON e.id = q.rsvpEventID
                       INNER JOIN ' . PRO_QUESTION_TYPE_TABLE . " qt ON qt.id = q.questionTypeID
                       WHERE (e.id = $rsvp_id OR e.parentEventID = $rsvp_id) AND
                         qt.questionType NOT IN ('hidden', 'readonly', 'file') AND
                         (IFNULL(e.event_access, '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "') != '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "'
                         OR (%d IN (SELECT rsvpAttendeeID FROM " . PRO_EVENT_ATTENDEE_TABLE . ' WHERE rsvpEventID = e.id)))) ',
				$attendee_id,
				$attendee_id
			)
		);
	}
	$qRs = $wpdb->get_results(
		$wpdb->prepare(
			'SELECT q.id, questionType, q.sortOrder, q.other_question FROM ' . PRO_QUESTIONS_TABLE . ' q
					INNER JOIN ' . PRO_QUESTION_TYPE_TABLE . " qt ON qt.id = q.questionTypeID
          WHERE q.rsvpEventID = %d AND `grouping` <> '" . RSVP_PRO_QG_MULTI . "'
          UNION
          SELECT q.id, questionType, q.sortOrder, q.other_question 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 = %d AND `grouping` <> '" . RSVP_PRO_QG_MULTI . "'
					ORDER BY sortOrder",
			$rsvp_id,
			$rsvp_id
		)
	);

	if ( count( $qRs ) > 0 ) {
		foreach ( $qRs as $q ) {
			if ( ( isset( $_POST[ $form_name . $q->id ] ) && ! empty( $_POST[ $form_name . $q->id ] ) ) || isset( $_FILES[ $form_name . $q->id ] ) || isset( $_POST['temp' . $form_name . $q->id ]) ) {
				if ( $q->questionType == QT_PRO_MULTI ) {
					$selectedAnswers = '';
					$aRs             = $wpdb->get_results( $wpdb->prepare( 'SELECT id, answer FROM ' . PRO_QUESTION_ANSWERS_TABLE . ' WHERE questionID = %d', $q->id ) );
					if ( ( count( $aRs ) > 0 ) && is_array( $_POST[ $form_name . $q->id ] ) ) {
						foreach ( $aRs as $a ) {
							if ( in_array( $a->id, $_POST[ $form_name . $q->id ] ) ) {
								$selectedAnswers .= ( ( strlen( $selectedAnswers ) == '0' ) ? '' : '||' ) . stripslashes( $a->answer );
							} elseif ( ( 'Y' === $q->other_question ) && in_array( 'other', $_POST[ $form_name . $q->id ] ) ) {
								$selectedAnswers .= ( ( strlen( $selectedAnswers ) == '0' ) ? '' : '||' ) . 'other--' . $_POST[ $form_name . $q->id . 'other' ];
							}
						}
					}

					if ( ! empty( $selectedAnswers ) ) {
						$wpdb->insert(
							PRO_ATTENDEE_ANSWERS,
							array(
								'attendeeID' => $attendee_id,
								'answer'     => stripslashes( $selectedAnswers ),
								'questionID' => $q->id,
							),
							array( '%d', '%s', '%d' )
						);
					}
				} elseif ( ( $q->questionType == QT_PRO_DROP ) || ( $q->questionType == QT_PRO_RADIO ) ) {
					$aRs = $wpdb->get_results( $wpdb->prepare( 'SELECT id, answer FROM ' . PRO_QUESTION_ANSWERS_TABLE . ' WHERE questionID = %d', $q->id ) );
					if ( count( $aRs ) > 0 ) {
						foreach ( $aRs as $a ) {
							if ( $a->id == $_POST[ $form_name . $q->id ] ) {
								$wpdb->insert(
									PRO_ATTENDEE_ANSWERS,
									array(
										'attendeeID' => $attendee_id,
										'answer'     => stripslashes( $a->answer ),
										'questionID' => $q->id,
									),
									array( '%d', '%s', '%d' )
								);
								break;
							}
						}

						if ( 'Y' === $q->other_question ) {
							if ( $_POST[ $form_name . $q->id ] === 'other' ) {
								$wpdb->insert(
									PRO_ATTENDEE_ANSWERS,
									array(
										'attendeeID' => $attendee_id,
										'answer'     => 'other--' . $_POST[ $form_name . $q->id . 'other' ],
										'questionID' => $q->id,
									),
									array( '%d', '%s', '%d' )
								);
							}
						}
					}
				} elseif ( $q->questionType == QT_PRO_FILE ) {
					if ( isset( $_FILES[ $form_name . $q->id ] ) && is_uploaded_file( $_FILES[ $form_name . $q->id ]['tmp_name'] ) ) {
						// These files need to be included as dependencies when on the front end.
						require_once( ABSPATH . 'wp-admin/includes/image.php' );
						require_once( ABSPATH . 'wp-admin/includes/file.php' );
						require_once( ABSPATH . 'wp-admin/includes/media.php' );

						// Retrieve the old answer so we can get the old file and delete it and replace it with a new one.
						$old_answer = $wpdb->get_row( $wpdb->prepare( 'SELECT id, answer FROM ' . PRO_ATTENDEE_ANSWERS . ' WHERE attendeeID = %d AND questionID = %d', $attendee_id, $q->id ) );
						if ( $old_answer !== null ) {
							wp_delete_attachment( $old_answer->answer );
							$wpdb->delete(
								PRO_ATTENDEE_ANSWERS,
								array( 'id' => $old_answer->id ),
								array( '%d' )
							);
						}
						$new_file_id = media_handle_upload( $form_name . $q->id, 0 );
						if ( ( false !== $new_file_id ) && is_int( $new_file_id ) ) {
							$wpdb->insert(
								PRO_ATTENDEE_ANSWERS,
								array(
									'attendeeID' => $attendee_id,
									'answer'     => $new_file_id,
									'questionID' => $q->id,
								),
								array( '%d', '%s', '%d' )
							);
						}
					} elseif ( isset( $_POST['temp' . $form_name . $q->id ] ) && !empty( $_POST['temp' . $form_name . $q->id ] ) ) {
						$file_id = get_transient( $_POST['temp' . $form_name . $q->id ] );
						if ( ( false !== $file_id ) && ( $file_id > 0 ) ) {
							// Retrieve the old answer so we can get the old file and delete it and replace it with a new one.
							$old_answer = $wpdb->get_row( $wpdb->prepare( 'SELECT id, answer FROM ' . PRO_ATTENDEE_ANSWERS . ' WHERE attendeeID = %d AND questionID = %d', $attendee_id, $q->id ) );
							if ( $old_answer !== null ) {
								wp_delete_attachment( $old_answer->answer );
								$wpdb->delete(
									PRO_ATTENDEE_ANSWERS,
									array( 'id' => $old_answer->id ),
									array( '%d' )
								);
							}
							$wpdb->insert(
								PRO_ATTENDEE_ANSWERS,
								array(
									'attendeeID' => $attendee_id,
									'answer'     => $file_id,
									'questionID' => $q->id,
								),
								array( '%d', '%s', '%d' )
							);
						}
					}
				} else {
					$wpdb->insert(
						PRO_ATTENDEE_ANSWERS,
						array(
							'attendeeID' => $attendee_id,
							'answer'     => $_POST[ $form_name . $q->id ],
							'questionID' => $q->id,
						),
						array( '%d', '%s', '%d' )
					);
				}
			}
		}
	}
}

function rsvp_pro_handleGroupQuestions( $attendee_id, $form_name = 'mainquestion' ) {
	global $wpdb;
	global $rsvp_id;

	$wpdb->query(
		$wpdb->prepare(
			'DELETE FROM ' . PRO_ATTENDEE_ANSWERS . ' WHERE attendeeID = %d AND
    			questionID IN (SELECT q.id FROM ' . PRO_QUESTIONS_TABLE . ' q
                   INNER JOIN ' . PRO_EVENT_TABLE . ' e ON e.id = q.rsvpEventID
                   INNER JOIN ' . PRO_QUESTION_TYPE_TABLE . " qt ON qt.id = q.questionTypeID
                   WHERE q.`grouping` = '" . RSVP_PRO_QG_MULTI . "' AND (e.id = $rsvp_id OR e.parentEventID = $rsvp_id) AND
                     qt.questionType NOT IN ('hidden', 'readonly', 'file') AND
                     (IFNULL(e.event_access, '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "') != '" . RSVP_PRO_PRIVATE_EVENT_ACCESS . "'
                     OR (%d IN (SELECT rsvpAttendeeID FROM " . PRO_EVENT_ATTENDEE_TABLE . ' WHERE rsvpEventID = e.id)))) ',
			$attendee_id,
			$attendee_id
		)
	);

	// Get associated attendees....
	$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)';

	$associatedAttendees = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $attendee_id ) );
	foreach ( $associatedAttendees as $aa ) {
		$sql = 'DELETE FROM ' . PRO_ATTENDEE_ANSWERS . ' WHERE attendeeID = %d AND 
			questionID IN (SELECT q.id FROM ' . PRO_QUESTIONS_TABLE . " q 
			INNER JOIN " . PRO_QUESTION_TYPE_TABLE . " qt ON qt.id = q.questionTypeID
			WHERE q.`grouping` = '" . RSVP_PRO_QG_MULTI . "' AND qt.questionType NOT IN ('file', 'hidden', 'readonly'))";
		$wpdb->query( $wpdb->prepare( $sql, $aa->id ) );
	}

	$qRs = $wpdb->get_results(
		$wpdb->prepare(
			'SELECT q.id, questionType, q.sortOrder FROM ' . PRO_QUESTIONS_TABLE . ' q
					INNER JOIN ' . PRO_QUESTION_TYPE_TABLE . " qt ON qt.id = q.questionTypeID
          WHERE q.rsvpEventID = %d AND q.`grouping` = '" . RSVP_PRO_QG_MULTI . "'
          UNION
          SELECT q.id, questionType, q.sortOrder 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 = %d AND `grouping` = '" . RSVP_PRO_QG_MULTI . "'
					ORDER BY sortOrder",
			$rsvp_id,
			$rsvp_id
		)
	);
	if ( count( $qRs ) > 0 ) {
		foreach ( $qRs as $q ) {
			if ( ( isset( $_POST[ $form_name . $q->id ] ) && ! empty( $_POST[ $form_name . $q->id ] ) ) || isset( $_FILES[ $form_name . $q->id ] ) ) {
				if ( $q->questionType == QT_PRO_MULTI ) {
					$selectedAnswers = '';
					$aRs             = $wpdb->get_results( $wpdb->prepare( 'SELECT id, answer FROM ' . PRO_QUESTION_ANSWERS_TABLE . ' WHERE questionID = %d', $q->id ) );
					if ( count( $aRs ) > 0 ) {
						foreach ( $aRs as $a ) {
							if ( in_array( $a->id, $_POST[ $form_name . $q->id ] ) ) {
								$selectedAnswers .= ( ( strlen( $selectedAnswers ) == '0' ) ? '' : '||' ) . stripslashes( $a->answer );
							}
						}
					}

					if ( ! empty( $selectedAnswers ) ) {
						$wpdb->insert(
							PRO_ATTENDEE_ANSWERS,
							array(
								'attendeeID' => $attendee_id,
								'answer'     => stripslashes( $selectedAnswers ),
								'questionID' => $q->id,
							),
							array( '%d', '%s', '%d' )
						);
						foreach ( $associatedAttendees as $aa ) {
							$wpdb->insert(
								PRO_ATTENDEE_ANSWERS,
								array(
									'attendeeID' => $aa->id,
									'answer'     => stripslashes( $selectedAnswers ),
									'questionID' => $q->id,
								),
								array( '%d', '%s', '%d' )
							);
						}
					}
				} elseif ( ( $q->questionType == QT_PRO_DROP ) || ( $q->questionType == QT_PRO_RADIO ) ) {
					$aRs = $wpdb->get_results( $wpdb->prepare( 'SELECT id, answer FROM ' . PRO_QUESTION_ANSWERS_TABLE . ' WHERE questionID = %d', $q->id ) );
					if ( count( $aRs ) > 0 ) {
						foreach ( $aRs as $a ) {
							if ( $a->id == $_POST[ $form_name . $q->id ] ) {
								$wpdb->insert(
									PRO_ATTENDEE_ANSWERS,
									array(
										'attendeeID' => $attendee_id,
										'answer'     => stripslashes( $a->answer ),
										'questionID' => $q->id,
									),
									array( '%d', '%s', '%d' )
								);

								foreach ( $associatedAttendees as $aa ) {
									$wpdb->insert(
										PRO_ATTENDEE_ANSWERS,
										array(
											'attendeeID' => $aa->id,
											'answer'     => stripslashes( $a->answer ),
											'questionID' => $q->id,
										),
										array( '%d', '%s', '%d' )
									);
								}
								break;
							}
						}
					}
				} elseif ( QT_PRO_FILE == $q->questionType ) {
					if ( isset( $_FILES[ $form_name . $q->id ] ) && is_uploaded_file( $_FILES[ $form_name . $q->id ]['tmp_name'] ) ) {
						// These files need to be included as dependencies when on the front end.
						require_once( ABSPATH . 'wp-admin/includes/image.php' );
						require_once( ABSPATH . 'wp-admin/includes/file.php' );
						require_once( ABSPATH . 'wp-admin/includes/media.php' );

						$new_file_id = media_handle_upload( $form_name . $q->id, 0 );
						if ( is_int( $new_file_id ) ) {

							// Retrieve the old answer so we can get the old file and delete it and replace it with a new one.
							$old_answer = $wpdb->get_row( $wpdb->prepare( 'SELECT id, answer FROM ' . PRO_ATTENDEE_ANSWERS . ' WHERE attendeeID = %d AND questionID = %d', $attendee_id, $q->id ) );
							if ( $old_answer !== null ) {
								wp_delete_attachment( $old_answer->answer );
								$wpdb->delete(
									PRO_ATTENDEE_ANSWERS,
									array( 'id' => $old_answer->id ),
									array( '%d' )
								);

								foreach ( $associatedAttendees as $aa ) {
									$wpdb->delete(
										PRO_ATTENDEE_ANSWERS,
										array( 'attendeeID' => $aa->id, 'questionID' => $q->id ),
										array( '%d', '%d' )
									);
								}
							}
							
							if ( false !== $new_file_id ) {
								$wpdb->insert(
									PRO_ATTENDEE_ANSWERS,
									array(
										'attendeeID' => $attendee_id,
										'answer'     => $new_file_id,
										'questionID' => $q->id,
									),
									array( '%d', '%s', '%d' )
								);

								foreach ( $associatedAttendees as $aa ) {
									$wpdb->insert(
										PRO_ATTENDEE_ANSWERS,
										array(
											'attendeeID' => $aa->id,
											'answer'     => $new_file_id,
											'questionID' => $q->id,
										),
										array( '%d', '%s', '%d' )
									);
								}
							}
						}
					}
				} else {
					$wpdb->insert(
						PRO_ATTENDEE_ANSWERS,
						array(
							'attendeeID' => $attendee_id,
							'answer'     => $_POST[ $form_name . $q->id ],
							'questionID' => $q->id,
						),
						array( '%d', '%s', '%d' )
					);
					foreach ( $associatedAttendees as $aa ) {
						$wpdb->insert(
							PRO_ATTENDEE_ANSWERS,
							array(
								'attendeeID' => $aa->id,
								'answer'     => $_POST[ $form_name . $q->id ],
								'questionID' => $q->id,
							),
							array( '%d', '%s', '%d' )
						);
					}
				}
			}
		}
	}
}

function rsvp_pro_auto_rsvp_attendees( $rsvp_event_id ) {
	global $wpdb;

	if ( ( rsvp_pro_get_event_option( $rsvp_event_id, RSVP_PRO_OPTION_ENABLE_WAITLIST ) == 'Y' ) && ( rsvp_pro_get_event_option( $rsvp_event_id, RSVP_PRO_OPTION_WAITLIST_AUTO_CHANGE ) == 'Y' ) ) {
		// Get limit and counts...
		$limit = rsvp_pro_get_event_option( $rsvp_event_id, RSVP_PRO_OPTION_EVENT_COUNT_LIMIT );
		$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() ) {
			$yesCount = $wpdb->get_var( $wpdb->prepare( $sql, $rsvp_event_id, $rsvp_event_id ) );
		} else {
			$yesCount = $wpdb->get_var( $wpdb->prepare( $sql, $rsvp_event_id ) );
		}

		if ( $limit > $yesCount ) {
			$numToAutoYes = ( $limit - $yesCount );
			// Auto set anyone to "yes" that is currently "waitlisted" and we have not hit the limit
			$sql = 'SELECT a.id, a.rsvpEventID FROM ' . PRO_ATTENDEES_TABLE . " a
					WHERE ( a.rsvpStatus = 'Waitlist' AND a.rsvpEventID = %d ) ";

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

			$sql .= ' ORDER BY rsvpDate DESC, id';
			if ( rsvp_pro_is_shared_attendee_list_enabled() ) {
				$attendees = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_event_id, $rsvp_event_id ) );
			} else {
				$attendees = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_event_id ) );
			}

			foreach ( $attendees as $a ) {
				if ( $numToAutoYes > 0 ) {
					$numToAutoYes --;
					if ( $a->rsvpEventID == RSVP_PRO_GLOBAL_ATTENDEE_EVENT_ID ) {
						$wpdb->update(
							PRO_ATTENDEE_SUB_EVENTS_TABLE,
							array( 'rsvpStatus' => 'Yes' ),
							array(
								'rsvpAttendeeID' => $a->id,
								'rsvpEventID'    => $rsvp_event_id,
							),
							array( '%s' ),
							array( '%d', '%d' )
						);
					} else {
						$wpdb->update(
							PRO_ATTENDEES_TABLE,
							array( 'rsvpStatus' => 'Yes' ),
							array( 'id' => $a->id ),
							array( '%s' ),
							array( '%d' )
						);
					}

					// Send notification...
					rsvp_pro_send_waitlist_status_change_notification( $rsvp_event_id, $a->id );
				}
			}
		}
	}
	// Look for the main event and see if there are any people that should be auto "yes"d
	// - Send notifications
	// Look at the sub-events and see if there are any people that should be auto "yes"d
	// - Send notifications
	$sql       = 'SELECT id FROM ' . PRO_EVENT_TABLE . ' WHERE parentEventID = %d';
	$subEvents = $wpdb->get_results( $wpdb->prepare( $sql, $rsvp_event_id ) );
	foreach ( $subEvents as $se ) {
		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_AUTO_CHANGE ) == 'Y' ) ) {
			// Get limit and counts...
			$limit    = rsvp_pro_get_sub_event_option( $se->id, RSVP_PRO_OPTION_EVENT_COUNT_LIMIT );
			$yesCount = $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(*) FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . " WHERE rsvpStatus = 'Yes' AND rsvpEventID = %d", $se->id ) );
			if ( $limit > $yesCount ) {
				$numToAutoYes = ( $limit - $yesCount );
				// Auto set anyone to "yes" that is currently "waitlisted" and we have not hit the limit
				$sql       = 'SELECT rsvpAttendeeID FROM ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . "
						WHERE rsvpStatus = 'Waitlist' AND rsvpEventID = %d
						ORDER BY rsvpDate DESC, id";
				$attendees = $wpdb->get_results( $wpdb->prepare( $sql, $se->id ) );
				foreach ( $attendees as $a ) {
					if ( $numToAutoYes > 0 ) {
						$numToAutoYes --;
						$wpdb->update(
							PRO_ATTENDEE_SUB_EVENTS_TABLE,
							array( 'rsvpStatus' => 'Yes' ),
							array( 'rsvpAttendeeID' => $a->rsvpAttendeeID ),
							array( '%s' ),
							array( '%d' )
						);
						// Send notification...
						rsvp_pro_send_waitlist_status_change_notification( $se->id, $a->rsvpAttendeeID );
					}
				}
			}
		}
	}
}

/**
 * This saves the changes that have occurred for a given attendee before they save
 * the changes to the database. The function only saves the change log if the
 * option is enabled in the "general settings" area of the RSVP Pro plugin.
 *
 * @param  int    $rsvp_id The RSVP ID we are wanting to save the changes for
 * @param  int    $attendee_id The attendee we are wanting to save any changes for
 * @param  string $primary_prefix The input element prefix that we will need to find information like their RSVP response
 * @param  string $custom_question_prefix The input element prefix to find the custom question changes
 * @param  string $sub_events_prefix The input element prefix to find the sub event information changes
 */
function rsvp_pro_save_attendee_changelog(
	$rsvp_id,
	$attendee_id,
	$primary_prefix,
	$custom_question_prefix,
	$sub_events_prefix
) {
	global $wpdb;
	if ( get_option( RSVP_PRO_GLOBAL_OPTION_ENABLE_ATTENDEE_CHANGELOG ) == 'Y' ) {
		$changed_information = array();
		// Get the person's saved RSVP information
		$sql      = 'SELECT a.id, firstName, lastName,  IFNULL(se.rsvpStatus, a.rsvpStatus) as rsvpStatus, note, 
                additionalAttendee, email, passcode, suffix, salutation, nicknames, 
                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';
		$attendee = $wpdb->get_row( $wpdb->prepare( $sql, $rsvp_id, $attendee_id ) );
		if ( $attendee != null ) {
			$rsvp_elem       = 'attending' . $attendee->id;
			$first_name_elem = 'attending' . $attendee->id . 'FirstName';
			$last_name_elem  = 'attending' . $attendee->id . 'LastName';
			$email_elem      = 'attending' . $attendee->id . 'Email';
			$note_elem       = 'rsvp_note';
			$passcode_elem   = 'attending' . $attendee->id . 'Passcode';
			$suffix_elem     = $primary_prefix . 'Suffix';
			$salutation_elem = $primary_prefix . ' Salutation';

			if ( $primary_prefix == 'main' ) {
				$rsvp_elem       = 'mainRsvp';
				$first_name_elem = 'attendeeFirstName';
				$last_name_elem  = 'attendeeLastName';
				$email_elem      = 'mainEmail';
				$passcode_elem   = 'attendeePasscode';
			}

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_FIRST_LAST_EDITABLE ) == 'Y' ) {
				$changed_information[] = rsvp_pro_check_if_value_changed( 'first_name', $attendee->firstName, $_POST[ $first_name_elem ] );
				$changed_information[] = rsvp_pro_check_if_value_changed( 'last_name', $attendee->lastName, $_POST[ $last_name_elem ] );
			}

			$current_status = '';
			if ( isset( $_POST[ $rsvp_elem ] ) ) {
				$current_status = rsvp_pro_translate_form_value_to_status( $_POST[ $rsvp_elem ] );
			}
			$changed_information[] = rsvp_pro_check_if_value_changed( 'rsvp_status', $attendee->rsvpStatus, $current_status );

			if ( $primary_prefix == 'main' && isset( $_POST[ $note_elem ] ) ) {
				$changed_information[] = rsvp_pro_check_if_value_changed( 'note', $attendee->note, $_POST[ $note_elem ] );
			}

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_HIDE_EMAIL_FIELD ) != 'Y' && isset( $_POST[ $email_elem ] ) ) {
				$changed_information[] = rsvp_pro_check_if_value_changed( 'email', $attendee->email, $_POST[ $email_elem ] );
			}

			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_PASSCODE_EDITABLE ) == 'Y' ) && isset( $_POST[ $passcode_elem ] ) ) {
				$changed_information[] = rsvp_pro_check_if_value_changed( 'passcode', $attendee->passcode, $_POST[ $passcode_elem ] );
			}

			if ( ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SUFFIX ) == 'Y' ) && isset( $_POST[ $suffix_elem ] ) ) {
				$changed_information[] = rsvp_pro_check_if_value_changed( 'suffix', $attendee->suffix, $_POST[ $suffix_elem ] );
			}

			if ( rsvp_pro_get_event_option( $rsvp_id, RSVP_PRO_OPTION_SHOW_SALUTATION ) == 'Y' ) {
				$tmp_val               = isset( $_POST[ $salutation_elem ] ) ? $_POST[ $salutation_elem ] : '';
				$changed_information[] = rsvp_pro_check_if_value_changed( 'salutation', $attendee->salutation, $tmp_val );
			}
		}

		// Get the person's saved custom question information
		$sql       = 'SELECT question, answer, ans.id AS answerID, q.ID AS questionID, questionType, `grouping` 
                FROM ' . PRO_QUESTIONS_TABLE . ' q
                LEFT JOIN ' . PRO_ATTENDEE_ANSWERS . ' ans ON ans.questionID = q.id AND attendeeID = %d
                INNER JOIN ' . PRO_QUESTION_TYPE_TABLE . ' qt ON qt.ID = q.questionTypeID
                WHERE q.rsvpEventID = %d
                ORDER BY q.sortOrder';
		$questions = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $rsvp_id ) );
		foreach ( $questions as $q ) {
			// Deal with normal and group questions
			if ( $q->grouping == RSVP_PRO_QG_MULTI ) {
				if ( isset( $_POST[ 'mainquestion' . $q->questionID ] ) ) {
					$changed_information[] = rsvp_pro_check_if_value_changed( stripslashes( $q->question ), $q->answer, $_POST[ 'mainquestion' . $q->questionID ] );
				}
			} else {
				if ( isset( $_POST[ $custom_question_prefix . $q->questionID ] ) ) {
					$changed_information[] = rsvp_pro_check_if_value_changed( stripslashes( $q->question ), $q->answer, $_POST[ $custom_question_prefix . $q->questionID ] );
				}
			}
		}

		// Get the person's saved sub-event saved information
		$sql       = 'SELECT e.id, se.id AS attendeeRecId, se.rsvpStatus, e.eventName
                FROM ' . PRO_EVENT_TABLE . ' e
                LEFT JOIN ' . PRO_ATTENDEE_SUB_EVENTS_TABLE . ' se ON se.rsvpEventID = e.id AND se.rsvpAttendeeID = %d
                WHERE e.parentEventID = %d';
		$subevents = $wpdb->get_results( $wpdb->prepare( $sql, $attendee_id, $rsvp_id ) );
		foreach ( $subevents as $se ) {
			if ( isset( $_POST[ $sub_events_prefix . 'RsvpSub' . $se->id ] ) ) {
				$rsvp_status = rsvp_pro_translate_form_value_to_status( $_POST[ $sub_events_prefix . 'RsvpSub' . $se->id ] );

				$changed_information[] = rsvp_pro_check_if_value_changed( stripslashes( $se->eventName ) . ' RSVP status', $se->rsvpStatus, $rsvp_status );
			}
		}

		$changed_information = array_filter( $changed_information );
		if ( count( $changed_information ) > 0 ) {
			// Save the changes to the database
			$wpdb->insert(
				PRO_ATTENDEE_CHANGELOG,
				array(
					'attendeeID'  => $attendee_id,
					'changes'     => json_encode( $changed_information ),
					'change_date' => date( 'Y-m-d H:i:s' ),
				),
				array( '%d', '%s', '%s' )
			);
		}
	}
}

/**
 * This function checks a field to see if the old and new value are different. If they
 * are then the old and new value are returned back in a changed array.
 *
 * @param  string $field_name The human friendly label for the field.
 * @param  string $old_value The current value stored in the database.
 * @param  string $new_value The new value stored in the database.
 *
 * @return null|array         If no changes then null, otherwise an array with the changed values.
 */
function rsvp_pro_check_if_value_changed( $field_name, $old_value, $new_value ) {

	if ( is_array( $new_value ) ) {
		$new_value = implode( ',', $new_value );
	}

	if ( strcasecmp( stripslashes( $old_value ), $new_value ) !== 0 ) {
		return array(
			'field'     => $field_name,
			'old_value' => stripslashes( $old_value ),
			'new_value' => $new_value,
		);
	}

	return null;
}

/**
 * This function was created to fulfill the requirement that when a new additional attendee is added
 * they copy the events the other main attendee has access to. The logic is that if the main user has
 * access to the event and they are adding an additional user they should have access as well...
 *
 * @param  int $copy_to_attendee_id the attendee we are copying to.
 * @param  int $copy_from_attendee_id the attendee we are copying from.
 */
function rsvp_pro_copy_event_permissions( $copy_to_attendee_id, $copy_from_attendee_id ) {
	global $wpdb;

	$sql = 'INSERT INTO ' . PRO_EVENT_ATTENDEE_TABLE . '(rsvpEventID, rsvpAttendeeID)
    	SELECT rsvpEventID, %d FROM ' . PRO_EVENT_ATTENDEE_TABLE .
		   ' WHERE rsvpAttendeeID = %d';

	$wpdb->query( $wpdb->prepare( $sql, $copy_to_attendee_id, $copy_from_attendee_id ) );
}
