<?php

/**
 * Description of BFrontRegistration
 *
 * @author nur
 */
class SwpmFrontRegistration extends SwpmRegistration {

	public static function get_instance() {
		self::$_intance = empty( self::$_intance ) ? new SwpmFrontRegistration() : self::$_intance;
		return self::$_intance;
	}

	public function regigstration_ui( $level ) {

		$settings_configs = SwpmSettings::get_instance();

		//Check if the hide rego from logged-in users feature is enabled before rendering the registration form.
		$hide_rego_to_logged_users = $settings_configs->get_value( 'hide-rego-form-to-logged-users' );
		if ( ! empty( $hide_rego_to_logged_users ) ){
			//Hide registration form to logged-in users feature is enabled. Check if the form should be hidden.
			if ( SwpmMemberUtils::is_member_logged_in() ) {
				$rego_hidden_to_logged_users_msg = '<div class="swpm_registration_hidden_to_logged_users_msg">';
				$rego_hidden_to_logged_users_msg .= '<div class="hide-rego-form-msg">' . SwpmUtils::_( "You are already logged in. You don't need to create another account. So the registration form is hidden." ) . '</div>';
				$rego_hidden_to_logged_users_msg .= '</div>';
				$rego_hidden_to_logged_users_msg = apply_filters('swpm_registration_form_hidden_message', $rego_hidden_to_logged_users_msg);
				return $rego_hidden_to_logged_users_msg;
			}
		}
		
		//Check if the registration completion link (if present in the URL) has been already used. Show an  appropriate error message to prevent confusion.
		if( SwpmUtils::is_registration_completion_link_already_used() ){
			$already_used_rego_complete_link_msg = '<div class="swpm_already_used_registration_complete_link_msg">';
			$already_used_rego_complete_link_msg .= SwpmUtils::_( "This unique registration link (see the URL in the browser's address bar) has already been used. You don't need to create another account. Log into the existing account to access the protected content." );
			$already_used_rego_complete_link_msg .= '</div>';
			$already_used_rego_complete_link_msg = apply_filters('swpm_already_used_registration_link_message', $already_used_rego_complete_link_msg);
			return $already_used_rego_complete_link_msg;
		}
		
		//Check if the registration completion link (if present in the URL) is invalid. Show an appropriate error message to prevent confusion (when they are clicking an invalid/deleted/old link).
		if( SwpmUtils::is_registration_completion_link_invalid() ){
				$rego_complete_link_invalid_msg = '<div class="swpm_registration_complete_link_invalid_msg">';
				$rego_complete_link_invalid_msg .= SwpmUtils::_( "This unique registration link (see the URL in the browser's address bar) is invalid. Could not find a match for the given member ID and the security code. Please contact the site administrator." );
				$rego_complete_link_invalid_msg .= '</div>';
				$rego_complete_link_invalid_msg = apply_filters('swpm_registration_completion_link_invalid_message', $rego_complete_link_invalid_msg);
				return $rego_complete_link_invalid_msg;
		}

		//Trigger the filter to override the registration form (the form builder addon uses this filter)
		$form = apply_filters( 'swpm_registration_form_override', '', $level ); //The $level value could be empty also so the code handling the filter need to check for it.
		if ( ! empty( $form ) ) {
			//An addon has overridden the registration form. So use that one.
			return $form;
		}

		$joinuspage_url = $settings_configs->get_value( 'join-us-page-url' );
		$membership_level = '';
		global $wpdb;

		if ( SwpmUtils::is_paid_registration() ) {
			//Lets check if this is a registration for paid membership
			$member = SwpmUtils::get_paid_member_info();
			if ( empty( $member ) ) {
				_e( 'Error! Invalid Request. Could not find a match for the given security code and the user ID.', 'simple-membership' );
			} else {
				$membership_level = $member->membership_level;
			}
		} elseif ( ! empty( $level ) ) {
			//Membership level is specified in the shortcode (level specific registration form).
			$member           = SwpmTransfer::$default_fields;
			$membership_level = absint( $level );
		}
                
		//Check if free membership registration is disalbed on the site
		if ( empty( $membership_level ) ) {
			$joinuspage_link         = '<a href="' . $joinuspage_url . '">' . SwpmUtils::_( 'Join Us' ) . '</a>';
			$free_rego_disabled_msg  = '<p>';
			$free_rego_disabled_msg .= SwpmUtils::_( 'Free membership is disabled on this site. Please make a payment from the ' );
			$free_rego_disabled_msg .= SwpmUtils::_( $joinuspage_link );
			$free_rego_disabled_msg .= SwpmUtils::_( ' page to pay for a premium membership.' );
			$free_rego_disabled_msg .= '</p><p>';
			$free_rego_disabled_msg .= SwpmUtils::_( 'You will receive a unique link via email after the payment. You will be able to use that link to complete the premium membership registration.' );
			$free_rego_disabled_msg .= '</p>';
			return $free_rego_disabled_msg;
		}

		//Handle the registration form in core plugin
		$membership_info = SwpmPermission::get_instance( $membership_level );
		$membership_level = $membership_info->get( 'id' );
		if ( empty( $membership_level ) ) {
			return 'Error! Failed to retrieve membership level ID from the membership info object.';
		}
		$level_identifier = md5( $membership_level );
		$membership_level_alias = $membership_info->get( 'alias' );
		$swpm_registration_submit = filter_input( INPUT_POST, 'swpm_registration_submit' );
		if ( ! empty( $swpm_registration_submit ) ) {
			$member = array_map( 'sanitize_text_field', $_POST );
		}
		ob_start();
		extract( (array) $member, EXTR_SKIP );

		$render_new_form_ui = $settings_configs->get_value('use-new-form-ui');
		if (!empty($render_new_form_ui)) {
			include SIMPLE_WP_MEMBERSHIP_PATH . 'views/add-v2.php';
		}else{
			include SIMPLE_WP_MEMBERSHIP_PATH . 'views/add.php';
		}
		return ob_get_clean();
	}

	public function register_front_end() {
		//Trigger action hook
		do_action( 'swpm_front_end_registration_form_submitted' );

		//If captcha is present and validation failed, it returns an error string. If validation succeeds, it returns an empty string.
		$captcha_validation_output = apply_filters( 'swpm_validate_registration_form_submission', '' );
		if ( ! empty( $captcha_validation_output ) ) {
			$message = array(
				'succeeded' => false,
				'message'   => SwpmUtils::_( 'Security check: captcha validation failed.' ),
			);
			SwpmTransfer::get_instance()->set( 'status', $message );
			return;
		}

		//Check if Terms and Conditions enabled
		$terms_enabled = SwpmSettings::get_instance()->get_value( 'enable-terms-and-conditions' );
		if ( ! empty( $terms_enabled ) ) {
			//check if user checked "I accept terms" checkbox
			if ( empty( $_POST['accept_terms'] ) ) {
				$message = array(
					'succeeded' => false,
					'message'   => SwpmUtils::_( 'You must accept the terms and conditions.' ),
				);
				SwpmTransfer::get_instance()->set( 'status', $message );
				return;
			}
		}

		//Check if Privacy Policy enabled
		$pp_enabled = SwpmSettings::get_instance()->get_value( 'enable-privacy-policy' );
		if ( ! empty( $pp_enabled ) ) {
			//check if user checked "I agree with Privacy Policy" checkbox
			if ( empty( $_POST['accept_pp'] ) ) {
				$message = array(
					'succeeded' => false,
					'message'   => SwpmUtils::_( 'You must agree to the privacy policy.' ),
				);
				SwpmTransfer::get_instance()->set( 'status', $message );
				return;
			}
		}

		//Validate swpm level hash data.
		$hash_val_posted = sanitize_text_field( $_POST['swpm_level_hash'] );
		$level_value     = SwpmForm::get_membership_level_from_request();
		$swpm_p_key      = get_option( 'swpm_private_key_one' );
		$hash_val        = md5( $swpm_p_key . '|' . $level_value );
		if ( $hash_val != $hash_val_posted ) {//Level hash validation failed.
			$msg  = '<p>Error! Security check failed for membership level validation.</p>';
			$msg .= '<p>The submitted membership level data does not seem to be authentic.</p>';
			$msg .= '<p>If you are using caching please empty the cache data and try again.</p>';
			wp_die( $msg );
		}

		$this->email_activation = get_option( 'swpm_email_activation_lvl_' . $level_value );

		//Crete the member profile and send notification
		if ( $this->create_swpm_user() ) {
			//SWPM user creation was successful. Now create the corresponding WP user record and send the notification email.
			if ( $this->prepare_and_create_wp_user_front_end() && $this->send_reg_email() ){
				do_action( 'swpm_front_end_registration_complete' ); //Keep this action hook for people who are using it (so their implementation doesn't break).
				do_action( 'swpm_front_end_registration_complete_user_data', $this->member_info );

				//Check if there is after registration redirect
				if ( ! $this->email_activation ) {
					$after_rego_url = SwpmSettings::get_instance()->get_value( 'after-rego-redirect-page-url' );
					$after_rego_url = apply_filters( 'swpm_after_registration_redirect_url', $after_rego_url );
					if ( ! empty( $after_rego_url ) ) {
						//Yes. Need to redirect to this after registration page
						SwpmLog::log_simple_debug( 'After registration redirect is configured in settings. Redirecting user to: ' . $after_rego_url, true );
						wp_redirect( $after_rego_url );
						exit( 0 );
					}
				}

				//Set the registration complete message
				if ( $this->email_activation ) {
					$email_act_msg  = '<div class="swpm-registration-success-msg">';
					$email_act_msg .= SwpmUtils::_( 'You need to confirm your email address. Please check your email and follow instructions to complete your registration.' );
					$email_act_msg .= '</div>';
									$email_act_msg = apply_filters( 'swpm_registration_email_activation_msg', $email_act_msg );//Can be added to the custom messages addon.
					$message        = array(
						'succeeded' => true,
						'message'   => $email_act_msg,
					);
				} else {
					$login_page_url = SwpmSettings::get_instance()->get_value( 'login-page-url' );

					// Allow hooks to change the value of login_page_url
					$login_page_url = apply_filters('swpm_register_front_end_login_page_url', $login_page_url);

					$after_rego_msg = '<div class="swpm-registration-success-msg">' . SwpmUtils::_( 'Registration Successful. ' ) . SwpmUtils::_( 'Please' ) . ' <a href="' . $login_page_url . '">' . SwpmUtils::_( 'Log In' ) . '</a></div>';
					$after_rego_msg = apply_filters( 'swpm_registration_success_msg', $after_rego_msg );
					$message        = array(
						'succeeded' => true,
						'message'   => $after_rego_msg,
					);
				}
				SwpmTransfer::get_instance()->set( 'status', $message );
				return;
			}
		}
	}

	/*
	 * This function creates/updates the SWPM user record in the database.
	 * It returns true if the user creation was successful. Otherwise, it returns false.
	 */
	private function create_swpm_user() {
		global $wpdb;
		$member = SwpmTransfer::$default_fields;
		$form   = new SwpmFrontForm( $member );
		if ( ! $form->is_valid() ) {
			$message = array(
				'succeeded' => false,
				'message'   => SwpmUtils::_( 'Please correct the following' ),
				'extra'     => $form->get_errors(),
			);
			SwpmTransfer::get_instance()->set( 'status', $message );
			return false;
		}

		$member_info = $form->get_sanitized_member_form_data();

		//Check if the email belongs to an existing wp user account with admin role.
        SwpmMemberUtils::check_and_die_if_email_belongs_to_admin_user($member_info['email']);

		//Go ahead and create the SWPM user record.
		$free_level                           = SwpmUtils::get_free_level();
		$account_status                       = SwpmSettings::get_instance()->get_value( 'default-account-status', 'active' );
		$member_info['last_accessed_from_ip'] = SwpmUtils::get_user_ip_address();
		$member_info['member_since']          = SwpmUtils::get_current_date_in_wp_zone(); //date( 'Y-m-d' );
		$member_info['subscription_starts']   = SwpmUtils::get_current_date_in_wp_zone(); //date( 'Y-m-d' );
		$member_info['account_state']         = $account_status;
		if ( $this->email_activation ) {
			$member_info['account_state'] = 'activation_required';
		}
		$plain_password = $member_info['plain_password'];
		unset( $member_info['plain_password'] );

		if ( SwpmUtils::is_paid_registration() ) {
			//Remove any empty values from the array. This will preserve address information if it was received via the payment gateway.
			$member_info = array_filter($member_info);

			//Handle DB insert for paid registration scenario.
			$member_info['reg_code'] = '';
			$member_id = filter_input( INPUT_GET, 'member_id', FILTER_SANITIZE_NUMBER_INT );
			$code = isset( $_GET['code'] ) ? sanitize_text_field( stripslashes ( $_GET['code'] ) ) : '';
			//Update the member record in the database.
			$query_result = $wpdb->update(
				$wpdb->prefix . 'swpm_members_tbl',/*table*/
				$member_info,/*data*/
				array(/*where*/
					'member_id' => $member_id,
					'reg_code'  => $code,
				)
			);

			//Verify that the update was successful. Otherwise, set error message and return false so the process stops here.
			if ( $query_result === false ) {
				SwpmLog::log_simple_debug( 'Error! Failed to update the member record on registration form submit. Check that the member ID ('.$member_id.') and the reg_code ('.$code.') are correct.', false );
				$message = array(
					'succeeded' => false,
					'message'   => SwpmUtils::_( 'Unexpected Error! Failed to update the member record. Enable the debug log file then try the process again to get more details.' ),
				);
				SwpmTransfer::get_instance()->set( 'status', $message );
				return false;
			}

			$query = $wpdb->prepare( 'SELECT membership_level FROM ' . $wpdb->prefix . 'swpm_members_tbl WHERE member_id=%d', $member_id );
			$member_info['membership_level'] = $wpdb->get_var( $query );
			$last_insert_id = $member_id;
		} elseif ( ! empty( $free_level ) ) {
			$member_info['membership_level'] = $free_level;
			//Create a new free member record in the database.
			$wpdb->insert( $wpdb->prefix . 'swpm_members_tbl', $member_info );
			$last_insert_id = $wpdb->insert_id;
		} else {
			$message = array(
				'succeeded' => false,
				'message'   => SwpmUtils::_( 'Membership Level Couldn\'t be found.' ),
			);
			SwpmTransfer::get_instance()->set( 'status', $message );
			return false;
		}
		$member_info['plain_password'] = $plain_password;
		$this->member_info = $member_info;
		return true;
	}

	private function prepare_and_create_wp_user_front_end() {
		global $wpdb;
		$member_info = $this->member_info;

		//Retrieve the user role assigned for this level
		$query     = $wpdb->prepare( 'SELECT role FROM ' . $wpdb->prefix . 'swpm_membership_tbl WHERE id = %d', $member_info['membership_level'] );
		$user_role = $wpdb->get_var( $query );
		//Check to make sure that the user role of this level is not admin.
		if ( $user_role == 'administrator' ) {
			//For security reasons we don't allow users with administrator role to be creted from the front-end. That can only be done from the admin dashboard side.
			$error_msg  = '<p>Error! The user role for this membership level (level ID: ' . $member_info['membership_level'] . ') is set to "Administrator".</p>';
			$error_msg .= '<p>For security reasons, member registration to this level is not permitted from the front end.</p>';
			$error_msg .= '<p>An administrator of the site can manually create a member record with this access level from the admin dashboard side.</p>';
			wp_die( $error_msg );
		}

		$wp_user_info                    = array();
		$wp_user_info['user_nicename']   = implode( '-', explode( ' ', $member_info['user_name'] ) );
		$wp_user_info['display_name']    = $member_info['user_name'];
		$wp_user_info['user_email']      = $member_info['email'];
		$wp_user_info['nickname']        = $member_info['user_name'];
		$wp_user_info['first_name']      = $member_info['first_name'];
		$wp_user_info['last_name']       = $member_info['last_name'];
		$wp_user_info['user_login']      = $member_info['user_name'];
		$wp_user_info['password']        = $member_info['plain_password'];
		$wp_user_info['role']            = $user_role;
		$wp_user_info['user_registered'] = date( 'Y-m-d H:i:s' );
		SwpmUtils::create_wp_user( $wp_user_info );
		return true;
	}

	public function edit_profile_front_end() {
		global $wpdb;
		//Check that the member is logged in
		$auth = SwpmAuth::get_instance();
		if ( ! $auth->is_logged_in() ) {
			return;
		}

		//Check nonce
		if ( ! isset( $_POST['swpm_profile_edit_nonce_val'] ) || ! wp_verify_nonce( $_POST['swpm_profile_edit_nonce_val'], 'swpm_profile_edit_nonce_action' ) ) {
			//Nonce check failed.
			wp_die( SwpmUtils::_( 'Error! Nonce verification failed for front end profile edit.' ) );
		}
                
                //Trigger action hook
                do_action( 'swpm_front_end_edit_profile_form_submitted' );
                
		$user_data = (array) $auth->userData;
		unset( $user_data['permitted'] );
		$form = new SwpmForm( $user_data );
		if ( $form->is_valid() ) {
			global $wpdb;
			$msg_str = '<div class="swpm-profile-update-success">' . SwpmUtils::_( 'Profile updated successfully.' ) . '</div>';
			$message = array(
				'succeeded' => true,
				'message'   => $msg_str,
			);

			$member_info = $form->get_sanitized_member_form_data();

                        //Check if membrship_level value has been posted.
                        if ( isset( $member_info['membership_level'] ) ){
                            //For edit profile, remove the membership level from the array (because we don't allow level updating in profile edit)
                            unset( $member_info['membership_level'] );
                        }

			SwpmUtils::update_wp_user( $auth->get( 'user_name' ), $member_info ); //Update corresponding wp user record.

			//Lets check if password was also changed.
			$password_also_changed = false;
			if ( isset( $member_info['plain_password'] ) ) {
				//Password was also changed.
				$msg_str = '<div class="swpm-profile-update-success">' . SwpmUtils::_( 'Profile updated successfully. You will need to re-login since you changed your password.' ) . '</div>';
				$message = array(
					'succeeded' => true,
					'message'   => $msg_str,
				);
				unset( $member_info['plain_password'] );
				//Set the password chagned flag.
				$password_also_changed = true;
			}

			//Update the data in the swpm database.
			$swpm_id = $auth->get( 'member_id' );
			//SwpmLog::log_simple_debug("Updating member profile data with SWPM ID: " . $swpm_id, true);
			$member_info = array_filter( $member_info );//Remove any null values.
			$wpdb->update( $wpdb->prefix . 'swpm_members_tbl', $member_info, array( 'member_id' => $swpm_id ) );
			$auth->reload_user_data();//Reload user data after update so the profile page reflects the new data.

			if ( $password_also_changed ) {
				//Password was also changed. Clear the user's auth cookies.
				$auth_object = SwpmAuth::get_instance();
				$auth_object->clear_wp_user_auth_cookies(); //Clear the wp user auth cookies and destroy session.
				$auth_object->swpm_clear_auth_cookies(); //Clear the swpm auth cookies. The user will be forced to login on the next page load.
				SwpmLog::log_simple_debug( 'Member has updated the password from profile edit page. Logging the user out so he can re-login using the new password.', true );
			}

			SwpmTransfer::get_instance()->set( 'status', $message );

			do_action( 'swpm_front_end_profile_edited', $member_info );
			return true; //Successful form submission.
		} else {
			$msg_str = '<div class="swpm-profile-update-error">' . SwpmUtils::_( 'Please correct the following.' ) . '</div>';
			$message = array(
				'succeeded' => false,
				'message'   => $msg_str,
				'extra'     => $form->get_errors(),
			);
			SwpmTransfer::get_instance()->set( 'status', $message );
			return false; //Error in the form submission.
		}
	}

	public function reset_password( $email ) {

		//If captcha is present and validation failed, it returns an error string. If validation succeeds, it returns an empty string.
		$captcha_validation_output = apply_filters( 'swpm_validate_pass_reset_form_submission', '' );
		if ( ! empty( $captcha_validation_output ) ) {
			$message = '<div class="swpm-reset-pw-error">' . SwpmUtils::_( 'Captcha validation failed.' ) . '</div>';
			$message = array(
				'succeeded' => false,
				'message'   => $message,
			);
			SwpmTransfer::get_instance()->set( 'status', $message );
			return;
		}

		$email = sanitize_email( $email );
		if ( ! is_email( $email ) ) {
			$message = '<div class="swpm-reset-pw-error">' . SwpmUtils::_( 'Email address not valid.' ) . '</div>';
			$message = array(
				'succeeded' => false,
				'message'   => $message,
			);
			SwpmTransfer::get_instance()->set( 'status', $message );
			return;
		}

		global $wpdb;
		$query = 'SELECT member_id,user_name,first_name, last_name FROM ' .
				$wpdb->prefix . 'swpm_members_tbl ' .
				' WHERE email = %s';

		$user  = $wpdb->get_row( $wpdb->prepare( $query, $email ) );
		if ( empty( $user ) ) {
			$message  = '<div class="swpm-reset-pw-error">' . SwpmUtils::_( 'No user found with that email address.' ) . '</div>';
			$message .= '<div class="swpm-reset-pw-error-email">' . SwpmUtils::_( 'Email Address: ' ) . $email . '</div>';
			$message  = array(
				'succeeded' => false,
				'message'   => $message,
			);
			SwpmTransfer::get_instance()->set( 'status', $message );
			return;
		}

		$settings = SwpmSettings::get_instance();
		$password_reset_link='';		
		$additional_args =array();
		$message  = '<div class="swpm-reset-pw-success-box">';
                
		$password_reset_using_link = $settings->get_value( 'password-reset-using-link' );
		if( $password_reset_using_link ) {
			$user_data = get_user_by( "email", $email );
			if( $user_data ) {
				$key = get_password_reset_key( $user_data );
				$user_login = $user_data->user_login;
				$password_reset_link = esc_url_raw( $settings->get_value("reset-page-url") . "?action=swpm-reset-using-link&key=$key&login=" . rawurlencode($user_login) );
				$additional_args["password_reset_link"] = $password_reset_link;

				//Skip the {password} tag
				$additional_args["password"] = "Reset password using link";

				SwpmLog::log_simple_debug( 'Reset password using link option is enabled.', true );
				$message .= '<div class="swpm-reset-pw-success">' . SwpmUtils::_( 'Password reset link has been sent to your email address.' ) . '</div>';
			}
		}
		else {
			$password = wp_generate_password();
                
			//Trigger a hook
			$password = apply_filters( 'swpm_password_reset_generated_pass', $password );
	
			$password_hash = SwpmUtils::encrypt_password( trim( $password ) );
			$wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'password' => $password_hash ), array( 'member_id' => $user->member_id ) );
	
			//Update wp user password
			add_filter( 'send_password_change_email', array( &$this, 'dont_send_password_change_email' ), 1, 3 ); //Stop WordPress from sending a reset password email to admin.
			SwpmUtils::update_wp_user( $user->user_name, array( 'plain_password' => $password ) );

			$additional_args["password"] = $password;
			SwpmLog::log_simple_debug( 'Member password has been reset.', true );
			$message .= '<div class="swpm-reset-pw-success">' . SwpmUtils::_( 'New password has been sent to your email address.' ) . '</div>';
		}

                //Password reset email header and subject.
		$from = $settings->get_value( 'email-from' );
		$headers = 'From: ' . $from . "\r\n";
                $subject = $settings->get_value( 'reset-mail-subject' );
                
                //Password reset email body
		$body = $settings->get_value( 'reset-mail-body' );
		$body = html_entity_decode( $body );
		//If the tag {password_reset_link} is not present in the email body, add it at the bottom of the email body.
		if( $password_reset_using_link && ( !SwpmMiscUtils::has_tag( $body, "{password_reset_link}" ) ) ) {
			$body .= "\n\nPassword Reset Link: {password_reset_link}";
		}
                //Merge tag replacement.
		$body = SwpmMiscUtils::replace_dynamic_tags( $body, $user->member_id, $additional_args );

                //Trigger the filters for password reset email subject and body.
		$subject = apply_filters( 'swpm_email_password_reset_subject', $subject );
		$body = apply_filters( 'swpm_email_password_reset_body', $body );

		SwpmMiscUtils::mail( $email, $subject, $body, $headers );
                SwpmLog::log_simple_debug( 'Member password reset email sent to: ' . $email, true );
		
		$message .= '<div class="swpm-reset-pw-success-email">' . SwpmUtils::_( 'Email Address: ' ) . $email . '</div>';
		$message .= '</div>';

		$message_ary = array(
			'succeeded'       => true,
			'message'         => $message,
			'pass_reset_sent' => true,
		);

		SwpmTransfer::get_instance()->set( 'status', $message_ary );
		
	}

	public function reset_password_using_link( $user_data, $password ) {
		$email = $user_data->user_email;
		
		global $wpdb;
		$query = 'SELECT member_id,user_name,first_name, last_name FROM ' .
				$wpdb->prefix . 'swpm_members_tbl ' .
				' WHERE email = %s';

		$user  = $wpdb->get_row( $wpdb->prepare( $query, $email ) );
		if ( empty( $user ) ) {
			$message  = '<div class="swpm-reset-pw-error">' . SwpmUtils::_( 'No user found with that email address.' ) . '</div>';
			$message .= '<div class="swpm-reset-pw-error-email">' . SwpmUtils::_( 'Email Address: ' ) . $email . '</div>';
			$message  = array(
				'succeeded' => false,
				'message'   => $message,
			);
			
			set_transient("swpm-passsword-reset-error",$message);
			SwpmLog::log_simple_debug( 'No member is found with email'.$user_data->user_email, true );
			return false;
		}
	
		$password_hash = SwpmUtils::encrypt_password( trim( $password ) );
		$wpdb->update( $wpdb->prefix . 'swpm_members_tbl', array( 'password' => $password_hash ), array( 'member_id' => $user->member_id ) );

		//Update wp user password
		add_filter( 'send_password_change_email', array( &$this, 'dont_send_password_change_email' ), 1, 3 ); //Stop WordPress from sending a reset password email to admin.
		SwpmUtils::update_wp_user( $user->user_name, array( 'plain_password' => $password ) );

		SwpmLog::log_simple_debug( 'Member password has been reset. Email: ' . $email, true );

		//Trigger action hook
		do_action( 'swpm_front_end_reset_password_using_link_completed', $user_data, $password);

		return true;
	}

	function dont_send_password_change_email( $send = false, $user = '', $userdata = '' ) {
		//Stop the WordPress's default password change email notification to site admin
		//Only the simple membership plugin's password reset email will be sent.
		return false;
	}

	public function email_activation() {
		$login_page_url = SwpmSettings::get_instance()->get_value( 'login-page-url' );

		// Allow hooks to change the value of login_page_url
		$login_page_url = apply_filters('swpm_email_activation_login_page_url', $login_page_url);

		$member_id = FILTER_INPUT( INPUT_GET, 'swpm_member_id', FILTER_SANITIZE_NUMBER_INT );

		$member = SwpmMemberUtils::get_user_by_id( $member_id );
		if ( empty( $member ) ) {
			//can't find member
			echo SwpmUtils::_( "Can't find member account." );
			wp_die();
		}
		if ( $member->account_state !== 'activation_required' ) {
			//account already active
			echo SwpmUtils::_( 'Account already active. ' ) . '<a href="' . $login_page_url . '">' . SwpmUtils::_( 'click here' ) . '</a>' . SwpmUtils::_( ' to log in.' );
			wp_die();
		}

		$code = isset( $_GET['swpm_token'] ) ? sanitize_text_field( stripslashes ( $_GET['swpm_token'] ) ) : '';
		$act_data = get_option( 'swpm_email_activation_data_usr_' . $member_id );
		if ( empty( $code ) || empty( $act_data ) || $act_data['act_code'] !== $code ) {
			//code mismatch
			wp_die( SwpmUtils::_( 'Activation code mismatch. Cannot activate this account. Please contact the site admin.' ) );
		}
		//activation code match
		delete_option( 'swpm_email_activation_data_usr_' . $member_id );
		//store rego form id in constant so FB addon could use it
		if ( ! empty( $act_data['fb_form_id'] ) ) {
			define( 'SWPM_EMAIL_ACTIVATION_FORM_ID', $act_data['fb_form_id'] );
		}
		$activation_account_status = apply_filters( 'swpm_activation_feature_override_account_status', 'active' );
		SwpmMemberUtils::update_account_state( $member_id, $activation_account_status );
		$this->member_info                   = (array) $member;
		$this->member_info['plain_password'] = SwpmUtils::crypt( $act_data['plain_password'], 'd' );
		$this->send_reg_email();

		$msg = '<div class="swpm_temporary_msg" style="font-weight: bold;">' . SwpmUtils::_( 'Success! Your account has been activated successfully.' ) . '</div>';

		// retrieving registered membership level details by the user.
		$membership_level = SwpmUtils::get_membership_level_row_by_id($member->membership_level);
		$custom_fields = SwpmMembershipLevelCustom::get_instance_by_id($membership_level->id);
		$after_activation_redirect_page = sanitize_url($custom_fields->get('after_activation_redirect_page'));

		// Check Whether the membership_level has a dedicated after activation redirect URL.
		if (!empty($after_activation_redirect_page)){
			$after_rego_url = $after_activation_redirect_page;
		}else{
			$after_rego_url = SwpmSettings::get_instance()->get_value( 'after-rego-redirect-page-url' );
		}

		$after_rego_url = apply_filters( 'swpm_after_registration_redirect_url', $after_rego_url );
		if ( ! empty( $after_rego_url ) ) {
			//Yes. Need to redirect to this after registration page
			SwpmLog::log_simple_debug( 'After registration redirect is configured in settings. Redirecting user to: ' . $after_rego_url, true );
			SwpmMiscUtils::show_temporary_message_then_redirect( $msg, $after_rego_url );
			exit( 0 );
		}

		//show success message and redirect to login page
		SwpmMiscUtils::show_temporary_message_then_redirect( $msg, $login_page_url );
		exit( 0 );
	}

	public function resend_activation_email() {
		$login_page_url = SwpmSettings::get_instance()->get_value( 'login-page-url' );

		// Allow hooks to change the value of login_page_url
		$login_page_url = apply_filters('swpm_resend_activation_email_login_page_url', $login_page_url);

		$member_id = FILTER_INPUT( INPUT_GET, 'swpm_member_id', FILTER_SANITIZE_NUMBER_INT );

		$member = SwpmMemberUtils::get_user_by_id( $member_id );
		if ( empty( $member ) ) {
			//can't find member
			echo SwpmUtils::_( 'Cannot find member account.' );
			wp_die();
		}
		if ( $member->account_state !== 'activation_required' ) {
			//account already active
			$acc_active_msg = SwpmUtils::_( 'Account already active. ' ) . '<a href="' . $login_page_url . '">' . SwpmUtils::_( 'click here' ) . '</a>' . SwpmUtils::_( ' to log in.' );
			echo $acc_active_msg;
			wp_die();
		}
		$act_data = get_option( 'swpm_email_activation_data_usr_' . $member_id );
		if ( ! empty( $act_data ) ) {
			//looks like activation data has been removed for some reason. We won't be able to have member's plain password in this case
			$act_data['plain_password'] = '';
		}

		delete_option( 'swpm_email_activation_data_usr_' . $member_id );

		$this->member_info                   = (array) $member;
		$this->member_info['plain_password'] = SwpmUtils::crypt( $act_data['plain_password'], 'd' );
		$this->email_activation              = true;
		$this->send_reg_email();

		$msg = '<div class="swpm_temporary_msg" style="font-weight: bold;">' . SwpmUtils::_( 'Activation email has been sent. Please check your email and activate your account.' ) . '</div>';
		SwpmMiscUtils::show_temporary_message_then_redirect( $msg, $login_page_url );
		wp_die();
	}

}
