<?php
/*
* Author : QuantumCloud
* class Handle Login, Password restore.
*/

class qc_sbd_login
{
	private static $instance;
	public static function instance(){
		if(!isset(self::$instance)){
			self::$instance = new qc_sbd_login();
		}
		return self::$instance;
	}
	private function __construct(){
		if( !is_admin() ){
			if(!session_id() && !headers_sent() ){
				session_start();
			}
		}
		$this->loadResources();
	}
	
	/*
	* Load Resources
	*/
	
	public function loadResources(){
		
		add_action( 'wp_enqueue_scripts', array($this,'pdcustom_login_enqueue_style') );
		
		add_action('template_redirect', array($this,'pdcustom_login_load_before_headers'));
		add_action( 'save_post', array($this,'pdcustom_login_get_pages_with_shortcodes') );
		add_shortcode('sbd_login', array($this,'pdcustom_login_show'));
		add_shortcode('sbd_restore', array($this,'pdcustom_login_restore_show'));
		// add_filter( 'wp_authenticate_user', array($this, 'pd_login_recaptcha_authenticate' ), 99, 2 );
		add_filter( 'authenticate', array($this, 'pd_login_recaptcha_authenticate' ), 99, 2 );

	}
	
	/*
	*Wp enqueue Script
	* Load stylesheet.
	*/
	public function pdcustom_login_enqueue_style(){
		wp_enqueue_script('qcld_pd_google_recaptcha', 'https://www.google.com/recaptcha/api.js', array('jquery'), '1.0.0', true);
	}

	public function pd_login_recaptcha_authenticate( $user, $username ){
		global $wp_query; 
		if ( is_singular() ) { 
			$post = $wp_query->get_queried_object();
			
			if( pd_ot_get_option('pd_enable_sbd_login_captcha') == 'on' ){
				$url = $this->pdcustom_login_url_cleaner( wp_get_referer() );

				if( pd_ot_get_option( 'pd_enable_recaptcha')=='off' ){				
					if(isset($_POST['ccode']) && strtolower($_POST['ccode'])!== strtolower($_POST['pdccode']) ){
						$url = esc_url( add_query_arg( 'authentication', 'invalid-captcha', $url ) );
						wp_safe_redirect( $url );exit;
					    return new WP_Error('invalid_captcha', __('Robot verification failed, please try again.','qc-opd'));
					}
				}

				if( pd_ot_get_option( 'pd_enable_recaptcha')=='on' ){
					if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])) {
				        $secret = pd_ot_get_option( 'pd_recaptcha_secret_key');

				        $verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response'] );
				        
				        $responseData = json_decode($verifyResponse);
				        if($responseData->success)
				        {
				            //$succMsg = 'Your contact request have submitted successfully.';
				        }
				        else
				        {
				        	$url = esc_url( add_query_arg( 'authentication', 'invalid-captcha', $url ) );
							wp_safe_redirect( $url );exit;
				        	return new WP_Error('invalid_captcha', __('Robot verification failed, please try again.','qc-opd'));
				        }
				    }else{
				    	$url = esc_url( add_query_arg( 'authentication', 'invalid-captcha', $url ) );
						wp_safe_redirect( $url );exit;
				    	return new WP_Error('invalid_captcha', __('Robot verification failed, please try again.','qc-opd'));
				    }
				}
			}

			// If contains any shortcode of our ones
			if ( $post && strpos($post->post_content, 'sbd' ) !== false ) {
				$url = $this->pdcustom_login_url_cleaner( wp_get_referer() );
				if ( !is_wp_error( $user ) ){
					$url = $this->pdcustom_login_get_translated_option_page( 'sbd_login_url','');
					wp_clear_auth_cookie();
				    wp_set_current_user ( $user->ID );
				    wp_set_auth_cookie  ( $user->ID );
					if(pd_ot_get_option('pd_enable_anyusers')=='on'){
						$url = $this->pdcustom_login_get_translated_option_page( 'sbd_dashboard_url','');
					}else{
						if(!in_array('pduser',$user->roles)){
							wp_logout();
							$url = esc_url( add_query_arg( 'authentication', 'disabled', $url ) );
						}else{
							$url = $this->pdcustom_login_get_translated_option_page( 'sbd_dashboard_url','');
						}
					}
					
					wp_safe_redirect( $url );exit;
				}
			}
		}
	    return $user;
	}
	
	/*
	* Shortcode pdcustom_login.
	*/
	public function pdcustom_login_show($atts){
		ob_start();
		
		$successfull_login_text = pd_ot_get_option('sbd_lan_successfully_logged_in') != '' ? pd_ot_get_option('sbd_lan_successfully_logged_in') : __( 'Successfully logged in!', 'qc-pd' );
		$failed_login_text = pd_ot_get_option('sbd_lan_failed_logged_in') != '' ? pd_ot_get_option('sbd_lan_failed_logged_in') : __( 'Wrong credentials or you are not allowed to logged in.', 'qc-pd' );
		$logout_text = pd_ot_get_option('sbd_lan_logout') != '' ? pd_ot_get_option('sbd_lan_logout') : __( 'Successfully logged out!', 'qc-pd' );
		$failed_activation_text = pd_ot_get_option('sbd_lan_failed_activate_user') != '' ? pd_ot_get_option('sbd_lan_failed_activate_user') : __( 'Something went wrong while activating your user', 'qc-pd' );
		$disabled_text = pd_ot_get_option('sbd_lan_disabled_user_area') != '' ? pd_ot_get_option('sbd_lan_disabled_user_area') : __( 'You are not allowed to access this area.', 'qc-pd' );
		$success_activation_text = pd_ot_get_option('sbd_lan_success_activation_user') != '' ? pd_ot_get_option('sbd_lan_success_activation_user') : __( 'Successfully activated', 'qc-pd' );

		if ( isset( $_GET['authentication'] ) ) {
			if ( $_GET['authentication'] == 'success' )
				echo "<div class='cleanlogin-notification success'><p>". $successfull_login_text ."</p></div>";
			else if ( $_GET['authentication'] == 'failed' )
				echo "<div style='color: red;border: 1px solid #e38484;margin: 2px;padding: 2px;text-align: center;margin-bottom: 8px;'>". $failed_login_text ."</div>";
			else if ( $_GET['authentication'] == 'invalid-captcha' )
				echo "<div style='color: red;border: 1px solid #e38484;margin: 2px;padding: 2px;text-align: center;margin-bottom: 8px;'>". __( 'Robot verification failed. Invalid Captcha', 'qc-pd' ) ."</div>";
			else if ( $_GET['authentication'] == 'logout' )
				echo "<div class='cleanlogin-notification success'><p>". $logout_text ."</p></div>";
			else if ( $_GET['authentication'] == 'failed-activation' )
				echo "<div class='cleanlogin-notification error'><p>". $failed_activation_text ."</p></div>";
					else if ( $_GET['authentication'] == 'disabled' )
				echo "<div class='cleanlogin-notification error'><p>". $disabled_text ."</p></div>";
			else if ( $_GET['authentication'] == 'success-activation' )
				echo "<div class='cleanlogin-notification success'><p>". $success_activation_text ."</p></div>";
		}

		if ( is_user_logged_in() ) {
					// show user preview data
			
			if(!function_exists('wp_get_current_user')) {
				include(ABSPATH . "wp-includes/pluggable.php"); 
			}
			$login_url = $this->pdcustom_login_get_translated_option_page( 'sbd_login_url','');
			$current_user = wp_get_current_user();
			$edit_url = $this->pdcustom_login_get_translated_option_page( 'pd_edit_url', '');
			$show_user_information = get_option( 'cl_hideuser' ) == 'on' ? false : true;
		?>

		<div class="cleanlogin-container" >
			<div class="cleanlogin-preview">
				<div class="cleanlogin-preview-top">
					<h2><?php echo pd_ot_get_option('sbd_lan_login_title') != '' ? pd_ot_get_option('sbd_lan_login_title') : __( 'Login', 'qc-pd' ) ?></h2>
				</div>
				<p style="    font-size: 14px;
			font-weight: bold;
			margin-bottom: 6px;"><?php echo pd_ot_get_option('sbd_lan_user_already_logged_in') != '' ? pd_ot_get_option('sbd_lan_user_already_logged_in') : __('User already logged in', 'qc-pd') ?></p>

				<a class="pd_logout_button" href="<?php echo esc_url( add_query_arg( 'action', 'logout', $login_url) ); ?>" class="cleanlogin-preview-logout-link"><?php echo pd_ot_get_option('sbd_lan_log_out') != '' ? pd_ot_get_option('sbd_lan_log_out') : __( 'Log out', 'qc-pd' ); ?></a>	
			</div>		
		</div>
		<?php
			
			
		} else {
	
	
			$login_url = $this->pdcustom_login_get_translated_option_page( 'sbd_login_url','');
			$register_url = $this->pdcustom_login_get_translated_option_page( 'pd_register_url', '');
			$restore_url = $this->pdcustom_login_get_translated_option_page( 'sbd_restore_url', '');
			$sbd_lan_only_password = pd_ot_get_option('sbd_lan_only_password') != '' ? pd_ot_get_option('sbd_lan_only_password') : __('Password', 'qc-pd');
			
		?>

		<div class="cleanlogin-container">		

			<form class="cleanlogin-form" method="post" action="<?php echo $login_url;?>">
				<h2> <?php echo (pd_ot_get_option('sbd_lan_login_title')!=''?pd_ot_get_option('sbd_lan_login_title'):__('Login', 'qc-pd')); ?></h2>
				
				<fieldset>
					<div class="cleanlogin-field">
						<input class="cleanlogin-field-username" type="text" name="log" placeholder="<?php echo (pd_ot_get_option('sbd_lan_username')!=''?pd_ot_get_option('sbd_lan_username'):__('Username or Email', 'qc-pd')); ?>">
					</div>
					
					<div class="cleanlogin-field">
						<input class="cleanlogin-field-password" type="password" name="pwd" placeholder="<?php echo $sbd_lan_only_password; ?>">
					</div>
					<?php
						if( pd_ot_get_option('pd_enable_sbd_login_captcha') == 'on' ){
							if( pd_ot_get_option( 'pd_enable_recaptcha')=='off' ){
								
								$_SESSION['sbd_captcha'] = pd_simple_php_captcha();
								
								echo '<fieldset><div class="cleanlogin-field">
								<img src="'.($_SESSION['sbd_captcha']['image_src']).'" alt="Captcha Code" id="pd_captcha_image_register" />
								<img style="width: 24px;cursor:pointer;" id="captcha_reload" src="'.QCSBD_IMG_URL.'/captcha_reload.png" />
								<input class="cleanlogin-field-username" placeholder="'. __( 'Code', 'qc-pd' ).'" type="text" name="ccode" id="sldcode" value="" required>
								<input type="hidden" name="pdccode" id="pdccode_register" value="'.($_SESSION['sbd_captcha']['sbd_code']).'" />
								</div></fieldset>
								 ';
							}

							if( pd_ot_get_option( 'pd_enable_recaptcha')=='on' ){
								echo '<div class="cleanlogin-field"><div class="g-recaptcha" data-sitekey="'.pd_ot_get_option( 'pd_recaptcha_site_key').'"></div></div>';
							}
						}
					?>

				</fieldset>
				
				<fieldset style="text-align:center; padding:0 !important;">
					<input class="cleanlogin-field submit_registration" type="submit" value="<?php echo (pd_ot_get_option('sbd_lan_login_with_space')!=''?pd_ot_get_option('sbd_lan_login_with_space'):__('Log in', 'qc-pd')); ?>" name="submit">
					<input type="hidden" name="action" value="login">
					
				</fieldset>
				
				<div class="cleanlogin-form-bottom">
					
					<div class="cleanlogin-field-remember">
						<?php 
							$create_account_text = pd_ot_get_option('sbd_lan_create_account') != '' ? pd_ot_get_option('sbd_lan_create_account') : __('Create Account', 'qc-pd');
							echo "<a style='float: right;color: #18191f ;font-weight: bold; padding-left:15px;' href='$register_url' class='cleanlogin-form-pwd-link'>". $create_account_text ."</a>";
						?>
					</div>

					<?php
						$forgot_pwd_text = pd_ot_get_option('sbd_lan_forgot_password') != '' ? pd_ot_get_option('sbd_lan_forgot_password') : __( 'Forgot your password?', 'qc-pd' );  
						echo "<a style='float: right;color: #666;font-weight: bold; padding-right:15px;' href='$restore_url' class='cleanlogin-form-pwd-link'>". $forgot_pwd_text ."</a>";
					?>
								
				</div>
				

			</form>
			<script type="text/javascript">
				jQuery("document").ready(function(){
					setTimeout(function(){
						jQuery('#captcha_reload').click();
					},1000)
				})
			</script>

		</div>
<?php
	$customCss = pd_ot_get_option( 'pd_custom_style' );
	if( trim($customCss) != "" ) :
?>
	<style>
		<?php echo trim($customCss); ?>
	</style>

<?php endif;
		}

		return ob_get_clean();
	}
	
	/**
	 * Custom code to be loaded before headers
	 */
	public function pdcustom_login_load_before_headers() {
		global $wp_query; 
		if ( is_singular() ) { 
			$post = $wp_query->get_queried_object();
			
			// If contains any shortcode of our ones
			if ( $post && strpos($post->post_content, 'sbd' ) !== false ) {

				// Sets the redirect url to the current page 
				$url = $this->pdcustom_login_url_cleaner( wp_get_referer() );
				

				// LOGIN
				if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'login' ) {
					
					$url = $this->pdcustom_login_get_translated_option_page( 'sbd_login_url','');

					$user = wp_signon();
					if ( is_wp_error( $user ) ){
						$url = esc_url( add_query_arg( 'authentication', 'failed', $url ) );
					}						
					else {
						// if the user is not pduser.

						if(pd_ot_get_option('pd_enable_anyusers')=='on'){
							$url = $this->pdcustom_login_get_translated_option_page( 'sbd_dashboard_url','');
						}else{
							if(!in_array('pduser',$user->roles)){
								wp_logout();
								$url = esc_url( add_query_arg( 'authentication', 'disabled', $url ) );
							}else{
								$url = $this->pdcustom_login_get_translated_option_page( 'sbd_dashboard_url','');
							}
						}
						
						
					}
					
					
					wp_safe_redirect( $url );exit;

				// LOGOUT
				} else if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'logout' ) {
					wp_logout();
					$url = esc_url( add_query_arg( 'authentication', 'logout', $url ) );
					wp_safe_redirect( $url );
				}// RESTORE a password by sending an email with the activation link
				 else if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'restore' ) {
					$url = esc_url( add_query_arg( 'sent', 'success', $url ) );
					
					$username = isset( $_POST['username'] ) ? sanitize_user( $_POST['username'] ) : '';
					$website = isset( $_POST['website'] ) ? sanitize_text_field( $_POST['website'] ) : '';
					// Since 1.1 (get username from email if so)
					if ( is_email( $username ) ) {
						$userFromMail = get_user_by( 'email', $username );
						if ( $userFromMail == false )
							$username = '';
						else
							$username = $userFromMail->user_login;
					}

					// honeypot detection
					if( $website != '.' )
						$url = esc_url( add_query_arg( 'sent', 'sent', $url ) );
					else if( $username == '' || !username_exists( $username ) )
						$url = esc_url( add_query_arg( 'sent', 'wronguser', $url ) );
					else {
						$user = get_user_by( 'login', $username );

						$url_msg = get_permalink();
						$url_msg = esc_url( add_query_arg( 'restore', $user->ID, $url_msg ) );
						$url_msg = wp_nonce_url( $url_msg, $user->ID );

						$email = $user->user_email;
						$blog_title = get_bloginfo();
						
						$mail_title_text  = pd_ot_get_option('sbd_lan_restore_user_password_email') != '' ? pd_ot_get_option('sbd_lan_restore_user_password_email') : 'Use the following link to restore your password:';
						$mail_link_text  = pd_ot_get_option('sbd_lan_restore_password') != '' ? pd_ot_get_option('sbd_lan_restore_password') : 'restore your password';

						$message = sprintf( __( '%1$s <a href=%2$s> %4$s </a> <br/><br/> %3$s <br/>', 'qc-pd' ), $mail_title_text, $url_msg, $blog_title, $mail_link_text );
						$subject = "[$blog_title] " . __( $mail_link_text, 'qc-pd' );
						// echo $message; die();
						add_filter( 'wp_mail_content_type', array($this,'pdcustom_login_set_html_content_type') );
						if( !wp_mail( $email, $subject , $message ) )
							$url = esc_url( add_query_arg( 'sent', 'failed', $url ) );
						remove_filter( 'wp_mail_content_type', array($this,'pdcustom_login_set_html_content_type') );
					}
					wp_safe_redirect( $url );

				// When a user click the activation link goes here to RESTORE his/her password
				} else if ( isset( $_REQUEST['restore'] ) ) {
					$user_id = $_REQUEST['restore'];
					$retrieved_nonce = $_REQUEST['_wpnonce'];
					if ( !wp_verify_nonce($retrieved_nonce, $user_id ) )
						die( 'Failed security check, expired Activation Link due to duplication or date.' );

					$edit_url = $this->pdcustom_login_get_translated_option_page( 'pd_edit_url', '');
					
					// If edit profile page exists the user will be redirected there
					if( $edit_url != '') {
						wp_clear_auth_cookie();
						wp_set_current_user ( $user_id );
						wp_set_auth_cookie  ( $user_id );
						$url = $edit_url;

					// If not, a new password will be generated and notified
					} else {
						$url = $this->pdcustom_login_get_translated_option_page( 'sbd_restore_url', '');
						// check if password complexity is checked
						$enable_passcomplex = get_option( 'pd_passcomplex' ) == 'on' ? true : false;
						
						if($enable_passcomplex)
							$new_password = wp_generate_password(12, true);
						else
							$new_password = wp_generate_password(8, false);

						$user_id = wp_update_user( array( 'ID' => $user_id, 'user_pass' => $new_password ) );

						if ( is_wp_error( $user_id ) ) {
							$url = esc_url( add_query_arg( 'sent', 'wronguser', $url ) );
						} else {
							// $url = esc_url( add_query_arg( 'pass', $new_password, $url ) );
							$url =  add_query_arg(
										array(
											'pass' => $new_password,
											'uid' => $user_id,
										), $url
									);
						}
					}

					wp_safe_redirect( $url );
				}elseif(
					(isset( $_POST['qcpd-restore-pwd'] ) && ($_POST['qcpd-restore-pwd'] == 'restore')) &&
					(isset( $_POST['qcpd-restore-pwd-type'] ) && ($_POST['qcpd-restore-pwd-type'] == 'user')) &&
					(isset( $_POST['qcpd-uid'] ) && absint($_POST['qcpd-uid']) > 0)
				){
					$user_id = absint($_POST['qcpd-uid']);
					$pass = sanitize_text_field($_POST['pass']);
					$edit_url = $this->pdcustom_login_get_translated_option_page( 'pd_edit_url', '');
					// If edit profile page exists the user will be redirected there
					if( $edit_url != '') {
						wp_clear_auth_cookie();
						wp_set_current_user ( $user_id );
						wp_set_auth_cookie  ( $user_id );
						$url = $edit_url;

					// If not, a new password will be generated and notified
					}else{
						$url = $this->pdcustom_login_get_translated_option_page( 'sbd_restore_url', '');
						$user_id = wp_update_user( array( 'ID' => $user_id, 'user_pass' => $pass ) );
						if ( is_wp_error( $user_id ) ) {
							$url = esc_url( add_query_arg( 'sent', 'wronguser', $url ) );
						} else {
							$url = $this->pdcustom_login_get_translated_option_page( 'sbd_login_url','');
						}
					}
					wp_safe_redirect( $url );
				}
			} 
		}
	}
	

	/**
	 * [pdcustom_restore] shortcode
	 */
	function pdcustom_login_restore_show($atts) {

		ob_start();

		$sbd_lan_mail_sent_success = pd_ot_get_option('sbd_lan_mail_sent_success') != '' ? pd_ot_get_option('sbd_lan_mail_sent_success') : __( 'You will receive an email with the activation link', 'qc-pd' ); 

		$sbd_lan_mail_sent_ok = pd_ot_get_option('sbd_lan_mail_sent_ok') != '' ? pd_ot_get_option('sbd_lan_mail_sent_ok') : __( 'You may receive an email with the activation link', 'qc-pd' ); 

		$sbd_lan_mail_sent_faild = pd_ot_get_option('sbd_lan_mail_sent_faild') != '' ? pd_ot_get_option('sbd_lan_mail_sent_faild') : __( 'An error has ocurred sending the email', 'qc-pd' ); 

		$sbd_lan_user_not_valid = pd_ot_get_option('sbd_lan_user_not_valid') != '' ? pd_ot_get_option('sbd_lan_user_not_valid') : __( 'Username is not valid', 'qc-pd' ); 

		if ( isset( $_GET['sent'] ) ) {
			if ( $_GET['sent'] == 'success' )
				echo "<div class='cleanlogin-notification success'><p>". $sbd_lan_mail_sent_success ."</p></div>";
			else if ( $_GET['sent'] == 'sent' )
				echo "<div class='cleanlogin-notification success'><p>". $sbd_lan_mail_sent_ok ."</p></div>";
			else if ( $_GET['sent'] == 'failed' )
				echo "<div class='cleanlogin-notification error'><p>". $sbd_lan_mail_sent_faild ."</p></div>";
			else if ( $_GET['sent'] == 'wronguser' )
				echo "<div class='cleanlogin-notification error'><p>". $sbd_lan_user_not_valid ."</p></div>";
		}

		if ( !is_user_logged_in() ) {
			if ( isset( $_GET['pass'] ) ) {
				require_once( QCSBD_DIR_MOD.'/login/pd-restore-new.php' );
			} else
				require_once( QCSBD_DIR_MOD.'/login/qc-restore-form.php' );
		} else {
			echo "<div class='cleanlogin-notification error'><p>". __( 'You are now logged in. It makes no sense to restore your account', 'qc-pd' ) ."</p></div>";
			require_once( QCSBD_DIR_MOD.'/login/qc-login-preview.php' );
		}

		return ob_get_clean();

	}
	
	/**
	 * Cleans an url
	 * @param url to be cleaned
	 */
	public function pdcustom_login_url_cleaner( $url ) {
		$query_args = array(
			'authentication',
			'updated',
			'created',
			'sent',
			'restore'
		);
		return esc_url( remove_query_arg( $query_args, $url ) );
	}
	
	/**
	 * SLD redirection support
	 */
	public function pdcustom_login_get_translated_option_page($page, $param = false) {
		$url = get_option($page, $param);
		//if SLD is installed get the page translation
		if (!function_exists('icl_object_id')) {
			return $url;
		} else {
			//get the page ID
			$pid = url_to_postid( $url ); 
			//set the translated urls
			return get_permalink( icl_object_id( $pid, 'page', false, ICL_LANGUAGE_CODE ) );
		}
	}
	
	
	
	/**
	 * Set email format to html
	 */
	public function pdcustom_login_set_html_content_type()
	{
		return 'text/html';
	}
	
	/**
	 * Detect shortcodes and update the plugin options
	 * @param post_id of an updated post
	 */
	function pdcustom_login_get_pages_with_shortcodes( $post_id ) {

		$revision = wp_is_post_revision( $post_id );

		if ( $revision ) $post_id = $revision;
		
		$post = get_post( $post_id );

		if ( has_shortcode( $post->post_content, 'sbd_login' ) ) {
			update_option( 'sbd_login_url', get_permalink( $post->ID ) );
		}
		
		if ( has_shortcode( $post->post_content, 'sbd_registration' ) ) {
			update_option( 'pd_register_url', get_permalink( $post->ID ) );
		}
		
		if ( has_shortcode( $post->post_content, 'sbd_dashboard' ) ) {
			update_option( 'sbd_dashboard_url', get_permalink( $post->ID ) );
		}elseif(strpos($post->post_content, '<li class="pdnav__list__item pdactive"><a href="">Dashboard</a></li>' ) !== false){
			update_option( 'sbd_dashboard_url', get_permalink( $post->ID ) );
		}
		
		if ( has_shortcode( $post->post_content, 'sbd_restore' ) ) {
			update_option( 'sbd_restore_url', get_permalink( $post->ID ) );
		}
		
		if ( has_shortcode( $post->post_content, 'sbd_claim_listing' ) ) {
			update_option( 'sbd_claim_url', get_permalink( $post->ID ) );
		}

	}
	
	
}

function qc_sbd_login_page() {
	return qc_sbd_login::instance();
}
qc_sbd_login_page();