<?php

/**
 *
 *	@module			quickform
 *	@version		see info.php of this module
 *	@authors		LEPTON project, Ruud Eisinga
 *	@copyright		2012-2022  LEPTON project (initial by Ruud Eisinga)
 *	@license		GNU General Public License
 *	@license terms	see info.php of this module
 *	@platform		see info.php of this module
 *
 *
 */


// include class.secure.php to protect this file and the whole CMS!
if (defined("LEPTON_PATH")) {
	include(LEPTON_PATH."/framework/class.secure.php");
} else {
	$root = "../";
	$level = 1;
	while (($level < 10) && (!file_exists($root."/framework/class.secure.php"))) {
		$root .= "../";
		$level += 1;
	}
	if (file_exists($root."/framework/class.secure.php")) {
		include($root."/framework/class.secure.php");
	} else {
		trigger_error(sprintf("[ <b>%s</b> ] Can't include class.secure.php!", $_SERVER["SCRIPT_NAME"]), E_USER_ERROR);
	}
}
// end include class.secure.php 

// save current time
$pageloadtime = time();

// get main instance
$oQUICKFORM = quickform::getInstance();

// get settings for section
$settings = $oQUICKFORM->get_settings( $section_id );

// get language setup
$MOD_QUICKFORM = $oQUICKFORM->language;

// get Page_link -- full path to the current frontend-page - aka. $oLEPTON->page_link() for a given page_id
global $oLEPTON;
$link = $database->get_one("SELECT `link` FROM `".TABLE_PREFIX."pages` WHERE `page_id` = '".PAGE_ID."'");

// initialize TWIG engine
$oTWIG = lib_twig_box::getInstance();
$oTWIG->registerModule("quickform");
$oQUICKFORM->oTWIG = $oTWIG;

// Define initial frontend data value array (will be extended below)
$page_values = array(
	 "PAGE_ID"				=> $page_id
	,"SECTION_ID"			=> $section_id
	,"DATE"					=> date( DATE_FORMAT , time() )
	,"TIME"					=> date( TIME_FORMAT , time() )
	,"TIMESTAMP"			=> $pageloadtime
	,'IP'					=> $_SERVER["REMOTE_ADDR"]

	,"settings"				=> $settings
	,"URL"					=> $oLEPTON->page_link( $link )
	
	,"STATUSMESSAGE"		=> ""		// used for error info but also for "thank you"
	,"MESSAGE_CLASS"		=> ""		// "hidden", "ok", "error" or classname
	,"FORM_CLASS"			=> ""		// "hidden", "" as default

	,"CAPTCHA"				=> ""		// set with captcha content related to selected captcha
	,"HONEYPOT_FIELD"		=> ""		// if switched on, it contains the randomly selected fieldname
	,"HONEYPOT_INDEX"		=> ""		// if switched on, it contains the index number of HONEYPOT_FIELD in field array

	,"REQUIRED_FIELDS"		=> ""		// array of form fields marked as required
	,"required_and_empty"	=> ""		// array of form fields marked as required but empty: maybe obsolete, not used in default templates
	,"IS_ERROR"				=> false	// general indication for errors

	,"oQCFE"				=> NULL
	,"CONTACT_ID"			=> get_leptoken()	// get a unique ID 
);

// identify action
$action = "show";
if (isset($_POST["quickform"]))		{ $action = "save"; }

// init error occured
$isError = false;

// get template file: path . language to use / template name
$template_path = __DIR__;
$template_lang = "";
$template_name = $settings["template"];
$template_exist = $oQUICKFORM->get_template( $page_id, $template_path, $template_lang, $template_name );
if ( $template_exist === false )
{
	$page_values["MESSAGE_CLASS"]	= "error";
	$page_values["STATUSMESSAGE"]	= $MOD_QUICKFORM["ERROR_TEMPLATE_MISSED"];
	$page_values["FORM_CLASS"]		= "hidden";
	$action							= "error";	// dummy action
	$isError						= true;
}

// add customized values if defined 
if ( class_exists("quickform_custom_frontend", true ))
{
	$oQCFE = quickform_custom_frontend::getInstance();
	$page_values[ "oQCFE" ] = $oQCFE;
	$oQUICKFORM->oQCFE = $oQCFE;
}
else
{
	$oQCFE = NULL;
	$oQUICKFORM->oQCFE = NULL;
}

// handle on incoming action
$template_fields = array();
$required_fields = array();
$spamcheck = 0;
switch( $action )
{
	/* -----------------------
	 * Show the contact form
	 * ----------------------- */
	case "show":
		// get a random honeypot field from list
		if ( $settings["use_honeypot"] == 1 )
		{
			if ( $settings["spam_honeypot"] )
			{
				$honeypots = explode( ",", $settings["spam_honeypot"] );
				$rand = array_rand( $honeypots );
				$page_values["HONEYPOT_FIELD"] = trim( $honeypots[$rand] );
				$page_values["HONEYPOT_INDEX"] = $rand;
			}

			// initial honeypot spammer check
			$spamcheck = $oQUICKFORM->spam_check( $action
											, sha1( $_SERVER['REMOTE_ADDR'] )
											, sha1( $_SERVER['HTTP_USER_AGENT'] )
											, $settings
											, $page_values
											, $pageloadtime
											, $page_values["HONEYPOT_FIELD"]
											, $page_values["HONEYPOT_INDEX"]
											);
		}

		// get all form fields inside the template
		$template_fields = $oQUICKFORM->get_template_fields(
		    $template_lang . DIRECTORY_SEPARATOR . $template_name,
		    $page_values["HONEYPOT_FIELD"]
		);

		// initialize submit fields
		foreach( $template_fields as $key=>$items )
		{
			// field is a submit field (name start with "qf_") and not yet defined in value list
			if ( $items[ "submit" ] === true )
			{
				if ( array_key_exists( $items["id"], $page_values ) === false )
				{
					$page_values[ $items["id"] ] = "";			// initialize value
				}
			}
			// build list of required fields
			if ( $items[ "required" ] === true )
			{
				$required_fields[] = $items["id"];
			}
		}
		$page_values[ "REQUIRED_FIELDS" ] = $required_fields;

		// add customized values if defined 
		if ( is_object( $oQCFE ) )
		{
			if (( method_exists( $oQCFE, 'set_page_values' ))
			&&  ( is_callable( array($oQCFE, 'set_page_values' )) ))
			{
				$status = $oQCFE->set_page_values( $template_fields, $page_values );
				switch ( (int)$status )
				{
				case 0:
					// failure
					$isError = true;
					break 2; 	// break status & action switch
				case 1:
					// success & continue
					break; 		// break status switch
				}
			}
		}

		// show form
		break;

	/* -----------------------
	 * react on submit: validate, show errors if any, send mail, save to DB, redirect to success page
	 * ----------------------- */
	case "save":
		// validate basic
		$oREQUEST = LEPTON_request::getInstance();
		$input_fields = array (
			 'quickform'	=> array ('type' => 'integer+', 'default' => 0)
			,'index'		=> array ('type' => 'integer+', 'default' => 9999)
			,'timestamp'	=> array ('type' => 'integer+', 'default' => 0)
		);
		$valid_fields = $oREQUEST->testPostValues($input_fields);

		// somethhing went wrong
		$quickform = $valid_fields["quickform"];
		if ( (int)$quickform !== (int)$section_id )
		{
			$page_values["MESSAGE_CLASS"]	= "error";
			$page_values["STATUSMESSAGE"]	= $MOD_QUICKFORM["ERROR_GENERIC"];
			$page_values["FORM_CLASS"]		= "hidden";
			$isError = true;
			break;	// break action switch
		}

		// get a random honeypot field from list
		$honeypotfield = NULL;
		$honeypotindex = NULL;
		if (( $settings["use_honeypot"] == 1 ) && ( $settings["spam_honeypot"] ))
		{
			$honeypots = explode( ",", $settings["spam_honeypot"] );

			// get currently used honeypot
			if ( isset( $valid_fields[ "index" ] ))
			{
				$honeypotindex = $valid_fields[ "index" ];
				if ( array_key_exists( $honeypotindex, $honeypots ) === true )
				{
					$honeypotfield = trim( $honeypots[ $honeypotindex ] );
				}
			}

			// get new honeypot
			$rand = array_rand( $honeypots );
			$page_values["HONEYPOT_INDEX"] = $rand;
			$page_values["HONEYPOT_FIELD"] = trim( $honeypots[$rand] );
		}

		// get all form fields inside the template
		$template_fields = $oQUICKFORM->get_template_fields( $template_lang . DIRECTORY_SEPARATOR . $template_name, $honeypotfield );

		// validate all received field values
		$input_fields = array();
		foreach( $template_fields as $key=>&$items )
		{
			$type = 'string_clean';
			switch ( $items[ "type" ] )
			{
				case "email":
					$type = 'email';
					break;
			}
			$input_fields[ $key ] = array ('type' => $type, 'default' => "");
		}
		$valid_fields = $oREQUEST->testPostValues($input_fields);	


		// get submitted values
		$required_and_empty = array();
		foreach( $template_fields as $key=>&$items )
		{
			if ( isset( $valid_fields[ $key ] ))
			{
				// get values
				$items[ "value" ] = $valid_fields[ $key ];
				if (( $items[ "value" ] == "" ) || ( $items[ "value" ] == "-" ) || ( $items[ "value" ] == false ))
				{
					$items[ "data-value" ] = $items[ "value" ];
				}

				// field is a submit field (name start with "qf_"), set received value back to form values list
				if ( $items[ "submit" ] === true )
				{
					$page_values[ $items["id"] ] = $items["value"];	// set value
				}
			}

			// is field required and set
			if ( $items[ "required" ] === true )
			{
				// build list of required fields
				$required_fields[] = $items["id"];

				// check if value is set
				if (( $items[ "value" ] == "" ) || ( $items[ "value" ] == "-" ))
				{
					$page_values[ $items["id"]  . "_ERROR" ] = "missing";	// set an "error" class
					$required_and_empty[] = $key;
					$isError = true;
				}
			}
		}
		$page_values[ "REQUIRED_FIELDS" ] = $required_fields;

		// not all submitted but required values have been set
		if ( true === $isError )
		{
			$page_values["MESSAGE_CLASS"]		= "error";
			$page_values["required_and_empty"]	= $required_and_empty;
			$page_values["STATUSMESSAGE"]		= $MOD_QUICKFORM["ERROR_REQUIRED_EMPTY"];
			
			// complete spammer check before react on error
		}

		// do honeypot spammer check
		if ( $settings["use_honeypot"] == 1 )
		{
			$page_values["TIMESTAMP"]	= $valid_fields['timestamp'];
			$spamcheck = $oQUICKFORM->spam_check( $action
											, sha1( $_SERVER['REMOTE_ADDR'] )
											, sha1( $_SERVER['HTTP_USER_AGENT'] )
											, $settings
											, $page_values
											, $pageloadtime
											, $honeypotfield
											, $honeypotindex
											);

			$tempTestValue = strtoupper( $honeypotfield ?? "LEPTONUNKNOWNHERE");
			if(isset($page_values[ $tempTestValue ]))
			{
				unset ($page_values[ $tempTestValue ]);    // gsm 2020-12-11
			}
			// remove honeypot from input
			unset ( $template_fields [ "qf_".$honeypotfield] );         // gsm 2020-12-11

            // spammer check failed
            if ((int)$spamcheck <= 0)
            {
                switch ((int)$settings["spam_failpage"])
                {
                    case 0:
                        // show a default text
                        $page_values["MESSAGE_CLASS"]   = "error";
                        $page_values["STATUSMESSAGE"]   = $MOD_QUICKFORM["SPAMMER_FINAL"] . " [ " . $spamcheck . " ]";
                        $page_values["FORM_CLASS"]      = "hidden";
                        break;  // break spam switch

                    default:
                        // open new page - this is "faild"
                        $link = $database->get_one("SELECT `link` FROM `".TABLE_PREFIX."pages` WHERE `page_id` = '" . $settings["spam_failpage"] . "'");
                        $failed_link = $oLEPTON->page_link($link);
                        die(header("location: ".$failed_link));
                }
                break;  // break action switch
            }
        }

		// not all submitted but required values have been set
		if (true === $isError)
		{
			break;	// break action switch
		}

		// add customized values if defined 
		if (true === is_object($oQCFE))
		{
			if ((method_exists($oQCFE, 'validate'))
			&&  (is_callable(array($oQCFE, 'validate')) ))
			{
				$status = $oQCFE->validate( $template_fields, $page_values );
				switch ((int)$status)
				{
				case 0:
					// failure
					$isError = true;
					break 2; 	// break status & action switch
				case 1:
					// success & continue
					break; 		// break status switch
				default:
					// open new page
					$link = $database->get_one("SELECT `link` FROM `".TABLE_PREFIX."pages` WHERE `page_id` = '" . ( (int)$status * -1 ) . "'");
					$success_link = $oLEPTON->page_link( $link );
					die(header("location: ".$success_link));
				}
			}
		}

		// validate captcha
		if (file_exists( LEPTON_PATH."/modules/quickform/recaptcha.php"))
		{
			if (isset( $valid_fields["g-recaptcha-response"]))
			{
				require_once LEPTON_PATH."/modules/quickform/recaptcha.php";
				$captcha_result = quickform_recaptcha::test_captcha( $valid_fields["g-recaptcha-response"] );
				if ( $captcha_result["success"] !== true )
				{
					$isError = true;
				}
			}
		} 
		elseif (isset( $valid_fields["captcha"]))
		{
			if (isset($_SESSION["captcha".$section_id]))
			{
				if ($_SESSION["captcha".$section_id] != $valid_fields["captcha"])
				{
					$isError = true;
				}
			}
		}
		else
		{
			$result = captcha::getInstance()->test_captcha( $_POST['captcha'], $section_id );
			$isError = $result ? false : true;

		}

		// captcha validation failed
		if ( true === $isError )
		{
			$page_values["CAPTCHA_ERROR"]       = "error";	// set an "error" class on the field
			$page_values["MESSAGE_CLASS"]       = "error";	// set an "error" class on the form
			$page_values["required_and_empty"]  = $required_and_empty;
			$page_values["STATUSMESSAGE"]       = $MOD_QUICKFORM["ERROR_REQUIRED_EMPTY"] . " (" . $TEXT["CAPTCHA_VERIFICATION"] . ")";
			break;	// break action switch
		}

		// ---------------------------
		// mail to receivers
		$email_params = array();
			// send a cc_mail
		$isError = $oQUICKFORM->mail_send( $template_fields, "requestor", $settings, $email_params );
		if ( false === $isError )
		{
			// if no error occured (or no cc_mail has been send), send also mail to quickform admin
			$isError = $oQUICKFORM->mail_send( $template_fields, "quickform", $settings, $email_params );
		}
		if ( true === $isError )
		{
			$page_values["MESSAGE_CLASS"]	= "error";
			if ( is_array( $email_params[ "error" ] ))
			{
				$page_values["STATUSMESSAGE"]	= $MOD_QUICKFORM[ $email_params[ "error" ][0]] . "<br />(" . $email_params[ "error" ][1] . ")";
			}
			else
			{
				$page_values["STATUSMESSAGE"]	= $MOD_QUICKFORM[ $email_params[ "error" ]];
			}
			break;	// break action switch
		}

		// ---------------------------
		// save to DB only if no error occured till here
		$db_fields = array(
			 "section_id"		=> $section_id
			,"msg_group"		=> "INBOX"
			,"data"				=> $email_params[ "message" ]
			,"submitted_when"	=> time()
		);
		if ( false === $database->build_and_execute( "insert", TABLE_PREFIX."mod_quickform_data", $db_fields ) )
		{
			$page_values["MESSAGE_CLASS"]	= "error";
			$page_values["STATUSMESSAGE"]	= $MOD_QUICKFORM["ERROR_WRITE_DB"];
			break;	// break action switch
		}

		// forward to success page if any
	 	if ( (int)$settings["successpage"] > 0 )
	 	{
			$link = $database->get_one("SELECT `link` FROM `".TABLE_PREFIX."pages` WHERE `page_id` = '" . $settings["successpage"] . "'");
			$success_link = $oLEPTON->page_link( $link );
	 		die( header( "location: ".$success_link) );

	 	}

		// no error occured and success page is current page
		$page_values["MESSAGE_CLASS"]	= "ok";
		$page_values["STATUSMESSAGE"]	= $MOD_QUICKFORM["SUCCESS_THANKYOU"];
		$page_values["FORM_CLASS"]		= "hidden";
		break;	// break action switch
}

// set new captcha
$page_values["CAPTCHA"] = $oQUICKFORM->captcha( $section_id );

// set error info
$page_values[ "IS_ERROR" ] = $isError;

/* --------------------
 *	prepare and show backend template
 * -------------------- */
echo $oTWIG->render(
	"@quickform/" . $template_lang . DIRECTORY_SEPARATOR . $template_name
	,$page_values
);
