<?php

 
 
class Tac_FoolBotHoneyPot_ControllerPublic_Register extends XFCP_Tac_FoolBotHoneyPot_ControllerPublic_Register
{

	// SERVER is for my own needs, forum admins don't need this, but it's useful for me to spot patterns
	protected static $logSERVER = false; 

		
	// override so that the username / email is now passed to the field with the uuid
	// When overriding methods, you should always call the parent method to avoid conflicts / classhes with other plugins
	// now doing all the time for good practice!
	public function actionIndex()
	{
		
		$responseView = parent::actionIndex(); 
		
		// we are about to display the registration page
		// so lets start the timer and identify the user with the session cookie	
		$registrationTimer = $this->_getTimerModel()->getRegistrationTimer();
		if(!$registrationTimer) // this handles the case where a user makes a mistake and then re-completes the form in only a few seconds
		{			
			$this->_getTimerModel()->setRegistrationTimerStart();
		}		

		
		if ($responseView instanceof XenForo_ControllerResponse_View)
		{
			$params = $responseView->params;
			
			$username = "";	
			$email = "";
					
			$uuids = $this->_getHoneyPotModel()->getFeildUUIDs();
				
			if(array_key_exists("username", $params["fields"])){
				$username = $params["fields"]["username"];
			}			
			if(array_key_exists("email", $params["fields"])){
				$email = $params["fields"]["email"];
			}				
				
			$fields = array(
				'uuid1viaLoginBar' => $username,
				'uuid2viaLoginBar' => $email,		
			);

			
			$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
			if ($username !== '')
			{
				$writer->set('username', $username);
			}
			if ($email !== '')
			{
				$writer->set('email', $email);
			}
			
				return $this->_getRegisterFormResponse($fields, $writer->getErrors());

		}
		
		return $responseView;
	}
	
	

	
	
	

	// override so we can redirect to the new form template
	
	protected function _getRegisterFormResponse(array $fields, array $errors = array())
	{
		$responseView = parent::_getRegisterFormResponse($fields, $errors);
		
		$params = $responseView->params;
		$options = XenForo_Application::get('options');				
		$uuids = $this->_getHoneyPotUUIDsModel()->setUuids();
		
		
		$fields["uuid1"] = (array_key_exists('uuid1viaLoginBar', $fields) ? $fields['uuid1viaLoginBar'] : $this->_input->filterSingle($uuids['1'], XenForo_Input::STRING));	// 'username' 
		$fields["uuid2"] = (array_key_exists('uuid2viaLoginBar', $fields) ? $fields['uuid2viaLoginBar'] : $this->_input->filterSingle($uuids['2'], XenForo_Input::STRING));	// 'email' 
		$fields["uuid5"] = $this->_input->filterSingle($uuids['5'], XenForo_Input::STRING);	// 'timezone' 
		$fields["uuid6"] = $this->_input->filterSingle($uuids['6'], XenForo_Input::STRING);	// 'gender'
		

		
		
		if(array_key_exists("timezone", $params["fields"])){
			$fields[$uuids['5']] = $responseView->params["fields"]["timezone"];
		}
		if(array_key_exists("timezoneAuto", $params["fields"])){
			$fields['timezoneAuto'] = $responseView->params["fields"]["timezoneAuto"]; 
		}
		
		// here we merge the parent::responseView to work with other mods 

		$name_field_templates = array(
			"Foolbothoneypot_uuid1_namefield1" => rand(1, 10),
			"Foolbothoneypot_uuid11_namefield2" => rand(1, 10),  
			"Foolbothoneypot_uuid12_namefield3"  => rand(1, 10),
			"Foolbothoneypot_uuid13_namefield4"  => rand(1, 10),
			"Foolbothoneypot_name_namefield5"  => rand(1, 10),			
			);
		asort($name_field_templates);
		
		$email_field_templates = array(
			"Foolbothoneypot_uuid2_emailfield1" => rand(1, 10),
			"Foolbothoneypot_emaildivfieldsblock" => rand(1, 10),  		
			);
		asort($email_field_templates);
	
		$pass_field_templates = array(
			"Foolbothoneypot_uuid3_4_passfield" => rand(1, 10),
			"Foolbothoneypot_uuid31_41_passfield" => rand(1, 10),  
			"Foolbothoneypot_uuid32_42_passfield"  => rand(1, 10),
			"Foolbothoneypot_uuid33_43_passfield"  => rand(1, 10),
			"Foolbothoneypot_pass_passfield"  => rand(1, 10),			
			);					
		asort($pass_field_templates);

		$gender_field_templates = array(
			"Foolbothoneypot_uuid6_genderfield" => rand(1, 10),
			"Foolbothoneypot_uuid61_genderfield" => rand(1, 10),  
			"Foolbothoneypot_uuid62_genderfield"  => rand(1, 10),
			"Foolbothoneypot_uuid63_genderfield"  => rand(1, 10),
			"Foolbothoneypot_gender_genderfield"  => rand(1, 10),			
			);					
		asort($gender_field_templates);	
				
		$timez_field_templates = array(
			"Foolbothoneypot_uuid5_timezfield" => rand(1, 10),
			"Foolbothoneypot_uuid51_timezfield" => rand(1, 10),  
			"Foolbothoneypot_uuid52_timezfield"  => rand(1, 10),
			"Foolbothoneypot_uuid53_timezfield"  => rand(1, 10),
			"Foolbothoneypot_timezone_timezfield"  => rand(1, 10),			
			);					
		asort($timez_field_templates);

		$disableHiddenTab = ($options->disableHiddenTab == 1? 1 : 0);
		
		
		$viewParams = $params;
				
		$viewParams['timez_field_templates'] = $timez_field_templates;
		$viewParams['gender_field_templates'] = $gender_field_templates;
		$viewParams['pass_field_templates'] = $pass_field_templates;
		$viewParams['email_field_templates'] = $email_field_templates;
		$viewParams['name_field_templates'] = $name_field_templates;
		$viewParams['uuids'] = $uuids;
		$viewParams['fields'] = $fields;
		$viewParams['disableHiddenTab'] = $disableHiddenTab;

	
		
		
		if(XenForo_Application::$versionId < 1020000) // allow this to work pre 1.2
		{
			return $this->responseView(
				'XenForo_ViewPublic_Register_Form',
				'Foolbothoneypot_register_form',
				$viewParams,
				$this->_getRegistrationContainerParams()
		);
			
		}
		
		// I'm now using template modifications rather than an alternative form
		return $this->responseView( 
			'XenForo_ViewPublic_Register_Form',
			'register_form',
			$viewParams,
			$this->_getRegistrationContainerParams()
		);
	}
	
	
		
	/**
	 * Registers a new user.
	 *
	 * @return XenForo_ControllerResponse_Abstract
	 */
	public function actionRegister()
	{
		 
		/*
		* $responseView = parent::actionRegister();
		* its not possible to make a call to the parent, since a bot that fills the hidden fields (name/email etc) 
		* would then "register" and be saved using the user datawriter, and we can not override the userdatawriter
		* to make a new required filled to force an "error", without serious consequences throughout 
		* For this reason, this plugin has to go before any other plugins that call the actionRegister
		* (we cant call parent::actionRegister since it's no longer expecting the normal params...
		* we could only do this if we can set _input
		*/
		
		
	
		$this->_assertPostOnly();
		$this->_assertRegistrationActive();

		$errors = array();
		
		$options = XenForo_Application::get('options');
		$SBModel = $this->_getFBHPStopBottersModel();
		
		$registrationTimer = $this->_getTimerModel()->getRegistrationTimer();
		// this table is going to get fairly big, this needs to be maintained, drop old sessions
		$this->_getTimerModel()->deleteOldRegistrationTimer();
		$registration_time = ($registrationTimer ? time() - $registrationTimer['time_start'] : 0);
		

				
		$tooFast = false;
		if ($options->fbhp_min_reg_time != 0 && $registration_time < $options->fbhp_min_reg_time)
		{
			$errors[] = new XenForo_Phrase('fbhp_you_completed_the_registration_faster_than_the_min_registration_time');
			$tooFast = true;
		}


		$uuids = $this->_getHoneyPotModel()->getFeildUUIDs();	
		// check that uuids have been set for this session, if they haven't something went wrong
		if (!$uuids)
		{
			// shouldn't get here
			$empty = array();
			$errors = array ("session time out, please start a new session");
			return $this->_getRegisterFormResponse($empty, $errors);
		}

		
		
			$hiddenData = $this->_input->filter(array(
				'username'   => XenForo_Input::STRING,
				'email'      => XenForo_Input::STRING,
				'timezone'   => XenForo_Input::STRING,
				'gender'     => XenForo_Input::STRING,
				'password'     => XenForo_Input::STRING,
				'password_confirm'     => XenForo_Input::STRING,
				
				$uuids['11']			=> XenForo_Input::STRING, // hidden username
				$uuids['21']				=> XenForo_Input::STRING, // hidden email
				$uuids['51']				=> XenForo_Input::STRING, // hidden timezone 
				$uuids['61']				=> XenForo_Input::STRING, // hidden gender 
				$uuids['31']     			=> XenForo_Input::STRING, // hidden password
				$uuids['41']     			=> XenForo_Input::STRING, // hidden password_confirm
					 
				$uuids['12']				=> XenForo_Input::STRING, // hidden username
				$uuids['22']				=> XenForo_Input::STRING, // hidden email
				$uuids['52']				=> XenForo_Input::STRING, // hidden timezone 
				$uuids['62']				=> XenForo_Input::STRING, // hidden gender 
				$uuids['32']     			=> XenForo_Input::STRING, // hidden password
				$uuids['42']     			=> XenForo_Input::STRING, // hidden password_confirm
					
				$uuids['13']				=> XenForo_Input::STRING, // hidden username
				$uuids['23']				=> XenForo_Input::STRING, // hidden email
				$uuids['53']				=> XenForo_Input::STRING, // hidden timezone 
				$uuids['63']				=> XenForo_Input::STRING, // hidden gender 
				$uuids['33']     			=> XenForo_Input::STRING, // hidden password
				$uuids['43']     			=> XenForo_Input::STRING, // hidden password_confirm				
			
			));
		
		// we need to check that the hidden fields havent been changed from default by a bot!
		$isBot = $this->_getHoneyPotModel()->getAlteredHiddenFields($hiddenData);
	
		// we need to check that javascript option is on, if on do they have javasctipt enables and has it updated correctly
		$clientSide = $this->_getClientSideModel()->getClientSide();
		$javascript_enabled = 1;$nonJSBot = false;
		if (!$clientSide || $clientSide['javascript_on'] == 0 || $clientSide['correct_uuid'] == 0)
		{
			$javascript_enabled = 0;
		}			
		if($options->fbhpJSBrowserOnly == 1 && $javascript_enabled == 0)
		{
			$errors[] = new XenForo_Phrase('fbhp_you_must_enable_javascript_in_order_to_register');	
			$nonJSBot = true;		
		}


		
		$captcha_passed = true;
		if (($isBot || $nonJSBot) && !XenForo_Captcha_Abstract::validateDefault($this->_input))
		{
			$errors[] = new XenForo_Phrase('did_not_complete_the_captcha_verification_properly');
			$captcha_passed = false;
		}
		
		
		
		
		
		
		
		// additional requirement to log bot-ness for CustomImgCaptcha		
		// check to see if CIC is installed
		$addonCIC = XenForo_Model::create('XenForo_Model_AddOn')->getAddOnById('CustomImgCaptcha');
		$addonCICActive = $addonCIC ? true : false; // check if AddOn is installed (else return false)
		if($addonCICActive){
			$addonCICActive = empty($addonCIC['active']) ? false : true;  // check that it's active
		}
		// check that it is selcted as an option:
		if($options->captcha != "Tac_CustomImgCaptcha_Captcha_Captcha")
		{
			$addonCICActive = false;	
		}	
		
		if($addonCICActive)
		{
			$public_uuid = $this->_input->filterSingle('public_uuid', XenForo_Input::STRING);
			// must get private uuid:
			if(!isSet($public_uuid))
			{
				$lastUUID = $this->_getUuidsModel()->getLastUUID();
				$private_uuid =  $lastUUID['private_uuid'];
			}
			else
			{	
				$cic_uuids = $this->_getUuidsModel()->getUuidsByPublicUuid($public_uuid);				
				$private_uuid =  $cic_uuids['private_uuid'];	
			}
		
			$counts = $this->_getCountsModel()->getCountsByUuid($private_uuid);
			$writer = XenForo_DataWriter::create('Tac_CustomImgCaptcha_DataWriter_Counts');
			// we now need to check that this user is human, check if ip address appears in FBHP logs
			$counts = $this->_getCountsModel()->getCountsByUuid($private_uuid);
			$CICWriter = XenForo_DataWriter::create('Tac_CustomImgCaptcha_DataWriter_Counts');
			if($counts)
			{
				$CICWriter->setExistingData($counts['id']);	
				$CICWriter->bulkSet($counts);
				
				if($captcha_passed)
				{
					if($isBot){$CICWriter->set('bot_passed', $counts['bot_passed'] + 1);}
					else{$CICWriter->set('human_passed', $counts['human_passed'] + 1);}
					
				}
				else
				{
					if($isBot){$CICWriter->set('bot_failed', $counts['bot_failed'] + 1);}
					else{$CICWriter->set('human_failed', $counts['human_failed'] + 1);}					
				}
				
			}
			else
			{
				
				
				if($captcha_passed)
				{
					if($isBot){$CICWriter->set('bot_passed', 1);}
					else{$CICWriter->set('human_passed', 1);}					
				}
				else
				{
					if($isBot){$CICWriter->set('bot_failed', 1);}
					else{$CICWriter->set('human_failed', 1);}						
				}
			}  
			$CICWriter->set('private_uuid', $private_uuid);            
	      	$CICWriter->save();	
		}
		
		
		
		
		
		
		$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');

		
		if($isBot != false)
		{		 
			$writer->error(new XenForo_Phrase('foolbothoneypot_sorry_youve_been_detected_as_an_automated_program', array('contact' => XenForo_Link::buildPublicLink('misc/contact') )), 'fbhp');	
		}
		
		

		
		$uuidData = $this->_input->filter(array(
			$uuids['1']   => XenForo_Input::STRING, // 'username' 
			$uuids['2']      => XenForo_Input::STRING, // 'email'  
			$uuids['5']   => XenForo_Input::STRING, // 'timezone' 
			$uuids['6']     => XenForo_Input::STRING, // 'gender'
			'dob_day'    => XenForo_Input::UINT, // 'dob_day'
			'dob_month'  => XenForo_Input::UINT, // 'dob_month'
			'dob_year'   => XenForo_Input::UINT, // 'dob_year
		));
		
		// since the uuidlong name isnt used in field.uuid1, we need to send the fields back as:
		$fieldData = array(
			'uuid1'  => $uuidData[$uuids['1']],  // 'username' 
			'uuid2'      => $uuidData[$uuids['2']], // 'email'  
			'uuid5'    => $uuidData[$uuids['5']], // 'timezone' 
			'uuid6'       => $uuidData[$uuids['6']], // 'gender'
			'dob_day'    => $uuidData['dob_day'], // 'dob_day'
			'dob_month'  =>  $uuidData['dob_month'], // 'dob_month'
			'dob_year'   =>  $uuidData['dob_year'], // 'dob_year
		);
		
		$data = array(
			'username'   => $uuidData[$uuids['1']],
			'email'      => $uuidData[$uuids['2']],
			'timezone'   => $uuidData[$uuids['5']],
			'gender'     => $uuidData[$uuids['6']],
			'dob_day'    => $uuidData['dob_day'],
			'dob_month'  => $uuidData['dob_month'],
			'dob_year'   => $uuidData['dob_year'],		
		);
		


		
		$uuidPasswords  = $this->_input->filter(array(
			$uuids['3']   => XenForo_Input::STRING, // 'password' 
			$uuids['4']      => XenForo_Input::STRING, // 'password_confirm'  
		));
		
		$passwords = array(
			'password' => $uuidPasswords[$uuids['3']],
			'password_confirm' => $uuidPasswords[$uuids['4']],
		);
		

	
		

		
		// AnyApi Integration
		$foundSpamAnyApi = false; $isSpamAnyApis = array();
			$addOnModel = $this->getModelFromCache('XenForo_Model_AddOn');
			if (($addon = $addOnModel->getAddOnById('anyApi')) && !empty($addon['active']) )	
			{		
				$dontCheckApiCaptchFail = $options->aaDontCheckApiCaptchFail;
				$dontCheckApiFBHPFail = $options->aaDontCheckApiFBPHFail;
				// dont check if FBHP option if($nonJSBot || $isBot)
				
				
				if( 
				($dontCheckApiCaptchFail == 0 || ($dontCheckApiCaptchFail == 1 && $captcha_passed == true)) && 
				($dontCheckApiFBHPFail == 0 || ($dontCheckApiFBHPFail == 1 && ($isBot == false && $nonJSBot == false) ))
				)
				{		
					$allApiStngs = $this->getModelFromCache('Tac_AnyApi_Model_ApiSettings')->getApiSettings();	
					$anyApiModel = $this->getModelFromCache('Tac_AnyApi_Model_AnyApi');
					$isSpamAnyApis = array();
					$visibleUsername = $fieldData['uuid1'];
					$visibleEmail = $fieldData['uuid2'];				
					foreach($allApiStngs as $key=>$apiSettings)
					{	
						$apiNo = 'api_'.$apiSettings['id'];
						$isSpamAnyApis[$apiNo] = array('isSpam' => $anyApiModel->isAnyApiBot($visibleUsername, $visibleEmail, $this->_input, $apiNo, $apiSettings), 'apiName' => $apiSettings['name'], 'id' => $apiSettings['id']);
					}		
					foreach($isSpamAnyApis as $key=>$isSpamAnyApi)
					{
						if($isSpamAnyApi['isSpam'] != false)
						{
							$foundSpamAnyApi = true;		 
							$writer->error(new XenForo_Phrase('anyapi_sorry_youve_been_detected_against_the_x_database', array('sitedb' => $isSpamAnyApi['apiName'])), $key);	
						}			
					}
				}	
			}
		
			
		
	
		
		
		if ($options->registrationDefaults)
		{
			$writer->bulkSet($options->registrationDefaults, array('ignoreInvalidFields' => true));
		}
		$writer->bulkSet($data);

		//$writer->setPassword($passwords['password'], $passwords['password_confirm']); //possible to create account without password?
		
		$writer->setPassword($passwords['password'], $passwords['password_confirm'], null, true);

		// if the email corresponds to an existing Gravatar, use it
		if ($options->gravatarEnable && XenForo_Model_Avatar::gravatarExists($data['email']))
		{
			$writer->set('gravatar', $data['email']);
		}

		$writer->set('user_group_id', XenForo_Model_User::$defaultRegisteredGroupId);
		$writer->set('language_id', XenForo_Visitor::getInstance()->get('language_id'));

		$customFields = $this->_input->filterSingle('custom_fields', XenForo_Input::ARRAY_SIMPLE);
		//$customFieldsShown = $this->_input->filterSingle('custom_fields_shown', XenForo_Input::STRING, array('array' => true));
		$customFieldsShown = array_keys(
			$this->_getFieldModel()->getUserFields(array('registration' => true))
		);
		
		$writer->setCustomFields($customFields, $customFieldsShown);

		$writer->advanceRegistrationUserState();
		$writer->preSave();

		if ($options->get('registrationSetup', 'requireDob'))
		{
			// dob required
			if (!$data['dob_day'] || !$data['dob_month'] || !$data['dob_year'])
			{
				$writer->error(new XenForo_Phrase('please_enter_valid_date_of_birth'), 'dob');
			}
			else
			{
				$userAge = $this->_getUserProfileModel()->getUserAge($writer->getMergedData(), true);
				if ($userAge < 1)
				{
					$writer->error(new XenForo_Phrase('please_enter_valid_date_of_birth'), 'dob');
				}
				else if ($userAge < intval($options->get('registrationSetup', 'minimumAge')))
				{
					// TODO: set a cookie to prevent re-registration attempts
					$errors[] = new XenForo_Phrase('sorry_you_too_young_to_create_an_account');
				}
			}
		}


		$username = $uuidData[$uuids['1']];	$email =  $uuidData[$uuids['2']];

		if(array_key_exists('username', $hiddenData ))
		{
			$username = (($hiddenData["username"] != "abaf1b4e8d0e34afa3") ? $hiddenData["username"] : $uuidData[$uuids['1']]);
		}
				
		if(array_key_exists('email', $hiddenData ))
		{		
			$email = (($hiddenData["email"] != "x@819978f0-0b0f-11e2-892e-0800200c9a66.com") ? $hiddenData["email"] : $uuidData[$uuids['2']]);
		}
		
		
		
		// report bots/humans that we do not know if they are bots
		$knownBotErrors = false;
		$apiKey = $options->fbhpStopBottersKey;
		$validateIP =  $options->fbhpStopBottersIP; 
		$validateEmail = $options->fbhpStopBottersEmail; 
		$validateUsername = $options->fbhpStopBottersUsername;
		if ($options->fbhpStopBottersEnabled == 1 && ($isBot == false || $javascript_enabled != 0 || !$username || !$email  ))
		{
			
			if ($knownBotErrors = $SBModel->stopBottersErrors('FBHPUser', $this->_input, $apiKey, $validateIP, $validateEmail, $validateUsername)) 
			{	
				$i = 0;
				foreach ($knownBotErrors as $knownBotError)
				{			
					$writer->error($knownBotError, 'knownbot'.$i);
					$i++;
				}
			}
		}		
		
		// report known bots (hidden fields and JS disabled, also has filled both hidden username and email 
		// -- unlikey that a user will modify all at once when testing)
		// or has alterd lots of fields in a small time from begining of session	
		if($isBot != false && $javascript_enabled == 0 && (($username && $email) ||  ($registration_time < 15 && count($isBot) > 2) )) 
		{
			if ($knownBotErrors = $SBModel->stopBottersErrors('FBHP', $this->_input, $apiKey, $validateIP, $validateEmail, $validateUsername)) 
			{
				if ($options->fbhpStopBottersEnabled == 1) 
				{	
					$i = 0;
					foreach ($knownBotErrors as $knownBotError)
					{			
						$writer->error($knownBotError, 'knownbot'.$i);
						$i++;
					}
				}
			}
			
			
						
		}		

		
		if (XenForo_Application::$versionId >= 1030000)
		{
			$ipAddress = XenForo_Helper_Ip::getBinaryIp(); 		
		}
		else
		{
			$ipAddress = $this->_getLoginModel()->convertIpToLong();
		}
				
		$errors = array_merge($errors, $writer->getErrors());
		$logEvents = ($options->fbhpLogEvents == 1 ? true : false);
		
			
		// log if detected as non bot
		if($isBot == false &&  $tooFast == false && $nonJSBot == false && !$knownBotErrors && $foundSpamAnyApi == false)
		{
			if ($logEvents && $options->fbhpLogPassed == 1)
			{
				$logWriter = XenForo_DataWriter::create('Tac_FoolBotHoneyPot_DataWriter_Log');	
				$logType = "No Bot Triggers Found";
				$logMsg = "FoolBotHoneyPot: Detected As Human - Registration Allowed";
				$isProxy = ($this->_getHoneyPotModel()->isProxy() != false ? $this->_getHoneyPotModel()->isProxy() : "No Proxy Detected");				
				$browser_plugins_detected = ($clientSide ? $clientSide['detected_plugins'] : "None");
				$found_on_stopbotters = ($knownBotErrors ? 1 : 0);
															
				$logWriter->set('log_date', XenForo_Application::$time);
				$logWriter->set('ip_address', $ipAddress);
				$logWriter->set('log_type', $logType);					
				$logWriter->set('altered_hidden_fields', serialize($isBot));
				$logWriter->set('registration_errors', serialize($errors));				
				$logWriter->set('message', $logMsg);
				
				$logWriter->set('username', $username);
				$logWriter->set('email', $email);
					
				$logWriter->set('user_agent', $_SERVER['HTTP_USER_AGENT']);
				$logWriter->set('port', $_SERVER['REMOTE_PORT']);
				if(self::$logSERVER)
				{
					$logWriter->set('server', serialize($_SERVER));
				}
				$logWriter->set('registration_time', $registration_time);
				$logWriter->set('is_proxy', $isProxy);
				$logWriter->set('browser_plugins_detected', $browser_plugins_detected);
				$logWriter->set('javascript_enabled', $javascript_enabled); 
				$logWriter->set('found_on_stopbotters', $found_on_stopbotters); 					
		
				$logWriter->save();	
			
				
			}	
		}	
	
		
		// log the data if detected as a bot or spam
		$users_ip = $_SERVER['REMOTE_ADDR'];
		if($isBot != false ||  $tooFast == true || $nonJSBot == true || $knownBotErrors || $foundSpamAnyApi != false)
		{
	
 
			$dontLogDupUsername = ($options->fbhpdontLogDupName == 1 ? true : false);
			$dontLogDupEmail = ($options->fbhpdontLogDupEmail == 1 ? true : false);
			$dontLogDupIP = ($options->fbhpdontLogDupIP == 1 ? true : false);
			if ($logEvents)
			{ 
				$logThisEvent = true;
								
				$logWriter = XenForo_DataWriter::create('Tac_FoolBotHoneyPot_DataWriter_Log');	
	
				if($username)
				{
					$logWriter->set('username', $username);
					$dupUsername = ($this->_getLogFBHPLogModel()->getLogByUsername($username) ? true : false);
					if ($dupUsername && $dontLogDupUsername && ($username != '')){$logThisEvent = false;}				
				}
				if($email)
				{
					$logWriter->set('email', $email);
					$dupEmail = ($this->_getLogFBHPLogModel()->getLogByEmail($email) ? true : false);
					if ($dupEmail && $dontLogDupIP && ($email != '')){$logThisEvent = false;}					 
				}	
	
				$dupIP = ($this->_getLogFBHPLogModel()->getLogByIP($ipAddress) ? true : false);			
				if ($dupIP && $dontLogDupIP){$logThisEvent = false;}
				
				
				
				$logType = "";
				if($isBot != false) {$logType .= "Hidden Fields Modifed, ";}
				if($tooFast == true) {$logType .= "Registration Too Fast, ";}
				if($nonJSBot == true){$logType .= "JavaScript Not Enabled, ";}
				if($knownBotErrors){$logType .= "Found on StopBotters, ";}
				
				$logMsg = "FoolBotHoneyPot: Detected As A Bot - Registration Blocked";
				// if it's found by an API but not FBHP, we don't it's a bot, it could just be spam
				
				if($isBot == false &&  $tooFast != true && $nonJSBot != true && !$knownBotErrors && $foundSpamAnyApi != false)
				{
					$logType = "Spam Triggers Found";
					$logMsg = "API: Detected As Spam - Registration Blocked";	
				}
				
				if($logThisEvent)
				{
					$isProxy = ($this->_getHoneyPotModel()->isProxy() != false ? $this->_getHoneyPotModel()->isProxy() : "No Proxy Detected");				
					$browser_plugins_detected = ($clientSide ? $clientSide['detected_plugins'] : "None");
					$found_on_stopbotters = ($knownBotErrors ? 1 : 0);	
														
					$logWriter->set('log_date', XenForo_Application::$time);
					$logWriter->set('ip_address', $ipAddress);
					$logWriter->set('log_type', $logType);					
					$logWriter->set('altered_hidden_fields', serialize($isBot));
					$logWriter->set('registration_errors', serialize($errors));				
					$logWriter->set('message', $logMsg);					
					$logWriter->set('user_agent', $_SERVER['HTTP_USER_AGENT']);
					$logWriter->set('port', $_SERVER['REMOTE_PORT']);
					if(self::$logSERVER)
					{
						$logWriter->set('server', serialize($_SERVER));
					}					
					$logWriter->set('registration_time', $registration_time);
					$logWriter->set('is_proxy', $isProxy);
					$logWriter->set('browser_plugins_detected', $browser_plugins_detected);
					$logWriter->set('javascript_enabled', $javascript_enabled); 
					$logWriter->set('found_on_stopbotters', $found_on_stopbotters);
					
					// logging anyAPI data	
					if($isSpamAnyApis)
					{		
						foreach($isSpamAnyApis as $key=>$isSpamAnyApi)
						{	
							$isSpamAnyApi['isSpam'] ? $logWriter->set('is_spam_api'.$isSpamAnyApi['id'], 1) : $logWriter->set('is_spam_api'.$isSpamAnyApi['id'], 0);
						}
					}	
					$logWriter->save();	
				}
			}	
		}
		
		
		if ($errors)
		{
			// $fields = $data; // original
			// $fields = $uuidData; // not quite, we are keeping the fielduuidnames: field.uuid1
			$fields = $fieldData;
			$fields['tos'] = $this->_input->filterSingle('agree', XenForo_Input::UINT);
			$fields['custom_fields'] = $customFields;
			
			return $this->_getRegisterFormResponse($fields, $errors);
		}

		
		// If there are no errors, we can get the parent instead of saving, 
		// but we must set all of the params 1st back to how they should be in the original:

		$_POST['username'] = $data['username'];
		$_POST['email'] = $data['email'];
		$_POST['timezone'] = $data['timezone'];
		$_POST['gender'] = $data['gender'];
		$_POST['password'] = $passwords['password'];
		$_POST['password_confirm'] = $passwords['password_confirm'];
		$_POST['dob_day'] = $data['dob_day'];
		$_POST['dob_month'] = $data['dob_month'];
		$_POST['dob_year'] = $data['dob_year'];	
				
		return parent::actionRegister();		
		
	}

	
	
	
	
	
	/**
	 * Validate a single field
	 *
	 * @return XenForo_ControllerResponse_Redirect
	 */
	public function actionValidateField()
	{
		$this->_assertPostOnly();

		$field = $this->_getFieldValidationInputParams();
		
		
		if (preg_match('/^custom_field_([a-zA-Z0-9_]+)$/', $field['name'], $match))
		{
		//	$writer = XenForo_DataWriter::create('XenForo_DataWriter_User');
		
		// since were are substituting the names for uuids, and can't extend controler, we will need to write our own datawriter
		// this datawriter can extend the XenForo_DataWriter_User 
			$writer = XenForo_DataWriter::create('Tac_FoolBotHoneyPot_DataWriter_User');
			
			$writer->setCustomFields(array($match[1] => $field['value']));

			if ($errors = $writer->getErrors())
			{
				return $this->responseError($errors);
			}

			return $this->responseRedirect(
				XenForo_ControllerResponse_Redirect::SUCCESS,
				'',
				new XenForo_Phrase('redirect_field_validated', array('name' => $field['name'], 'value' => $field['value']))
			);
		}
		else
		{
			// handle normal fields
			return $this->_validateField('Tac_FoolBotHoneyPot_DataWriter_User');
		}
	}
	
	
	public function actionClientSide()
	{
		// this is done via ajax, while the user is filling in the form, so we can do a lot of clean up / varification work here without having an impact on the user
		
		$this->_getClientSideModel()->deleteOldClientSide();
		// insert <no-script> to start with and allow script on the registraion form to update this (script sending can be forged, so I need to autheticate)
		$this->_getClientSideModel()->setClientSideStart();
		
		// set the cleintside values for this client session (can do only once)
		$uuid = $this->_input->filterSingle('uuid', XenForo_Input::STRING);
		$plugins = $this->_input->filterSingle('plugins', XenForo_Input::STRING);
		
		$this->_getClientSideModel()->updateClientSide($plugins, $uuid);
		
		return $this->responseError("This page is not for public view");	
		
	}

	public function actionFbhpVersion()
	{
		$v = $this->_getHoneyPotModel()->getFbhpVersion('FoolBotHoneyPot');
		$vDetails = $v['version_string']. " ".$v['version_id']." ".$v['uuid'];
		return $this->responseError("FoolBotHoneyPot Version: ".$vDetails );
	}
	
	
	public function actionKeyUpdateFbhp()
	{
		
		$options = XenForo_Application::get('options');
		$apiKey = $options->fbhpStopBottersKey; 
		$updated = $this->_getFBHPStopBottersModel()->updateKey($this->_input, $apiKey); 
		return $this->responseError("This page is not for public view");
	}	
	

	protected function _getHoneyPotUUIDsModel()
	{
		return $this->getModelFromCache('Tac_FoolBotHoneyPot_Model_Uuids');
	}		
	
	protected function _getClientSideModel()
	{
		return $this->getModelFromCache('Tac_FoolBotHoneyPot_Model_ClientSide');
	}	
		
	protected function _getTimerModel()
	{
		return $this->getModelFromCache('Tac_FoolBotHoneyPot_Model_Timer');
	}
	
	protected function _getHoneyPotModel()
	{
		return $this->getModelFromCache('Tac_FoolBotHoneyPot_Model_HoneyPot');
	}	
	
	protected function _getLogFBHPLogModel()
	{
		return $this->getModelFromCache('Tac_FoolBotHoneyPot_Model_Log');
	}

	protected function _getCountsModel()
	{
		return $this->getModelFromCache('Tac_CustomImgCaptcha_Model_Counts');
	}
	
	protected function _getUuidsModel()
	{
		return $this->getModelFromCache('Tac_CustomImgCaptcha_Model_Uuids');
	}		

	protected function _getFBHPStopBottersModel()
	{
		return $this->getModelFromCache('Tac_FoolBotHoneyPot_Model_StopBotters');
	}	

		

	
		
}