<?php

// this needs a clean up, most of this should be put in the spam model

class Tac_StopCountrySpam_ControllerPublic_Register extends XFCP_Tac_StopCountrySpam_ControllerPublic_Register
{

	/**
	 * Usualy displays a form to register a new user.
	 * But now, if the users IP address is from a country
	 * Selected in the Admin control panel, send them to
	 * new_registrations_currently_not_being_accepted
	 * @return XenForo_ControllerResponse_Abstract
	 */
	public function actionIndex()
	{
		$responseView = parent::actionIndex();
		$params = $responseView->params;
		$options = XenForo_Application::get('options');
		
		// we dont want to stop logging in, just registering
	
		// first, get the JSON response:
		// note, this wont work on a localhost testing environment (the IP address is 127.0.0.1)		
		
		// if the user has not added a jsonRequest, just return parent
		if(!$options->jsonRequest)
		{
			return $responseView;
		}
		
		
		$users_ip = $_SERVER['REMOTE_ADDR']; 		
				
		$selectedCountries = $options->spamCountries;
		$ListingType = ($options->blackOrWhite == 1 ? "Black" : "White");
		$jsonRequest = str_replace('{$ip}', $users_ip, $options->jsonRequest);
		$countryCodeIndex = $options->countryCodeIndex;
		$isBlockedFromRegistering = false;
		$contry2char = "";
		$jsonResponse = "";
		try {
			
			
			// get the response from the session, if its not set, then set it
			// this avoids api hammering for the same session	
			$jsonResponse = XenForo_Application::getSession()->get('SCSJsonResponse');
			
			if(!$jsonResponse)
			{
				/* to do, if we still don't have the response, we could check the response in the last 48 hours from local db */
				$jsonResponse = file_get_contents($jsonRequest);
				XenForo_Application::getSession()->set('SCSJsonResponse', $jsonResponse);	
			}
			
				
			
			
			
			$json = json_decode($jsonResponse,true);
			if($json == NULL)
			{	    		
	   	 		$jsonResponseIndexQuoteFix = preg_replace('/(\w+):/i', '"\1":', $jsonResponse);
	    		$json = json_decode($jsonResponseIndexQuoteFix,true);
			}
			
			
			
			/*
			* we also have to deal with nested indexes
			* nested indexes can be used in the format index1['index2']["index3"][index4]
			* this is a mixed format, but we may as well support, since supporting this will support pure/"correct" formats
			* and be lenient on user error.
			* For example, country['code'] is valid, as is country['code']['2digit'], as is country['code'][2digit]
			*/
			
			$isNested = strrpos($countryCodeIndex, "[");
			if ($isNested > 0) 
			{ 
				/* split this index1['index2']["index3"][index4]
				* into this: array ("index1","index2","index3","index4")
				* 1) strip out ',",] => index1[index2[index3[index4
				* 2) no brainer, split by [
				*/
				
				$stripOut = str_replace(array('"',  "'", "]", " " ), '',$countryCodeIndex);
        		$countryCodeIndexes = explode("[", $stripOut);       			
        		
        		
        		$nestSize = count($countryCodeIndexes);
        		
        		switch ($nestSize) {
				    case 0:
				        break;
				    case 1:
				        $contry2char = $json[$countryCodeIndexes[0]];
				        break;
				    case 2:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]];
				        break;
				    case 3:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]][$countryCodeIndexes[2]];
				        break;
				    case 4:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]][$countryCodeIndexes[2]][$countryCodeIndexes[3]];
				        break;
				}
			}					
			else if($countryCodeIndex == "" || $countryCodeIndex == "(none)" || $countryCodeIndex == "none"){
				$contry2char = $jsonResponse;
			}			
			else 
			{

				$contry2char = $json[$countryCodeIndex];
			}
		}
		catch (Exception $e) 
		{	
			$jsonResponse = $e->getMessage();
			$countryCodeIndexes = $contry2char = '';
	    	// no need to do anything, if the JSON site is down we don't want to stop registration / throw up errors to the user	
		}	
		
		
		$isBlockedFromRegistering = ($contry2char ? $this->_getSpamModel()->getBlockedFromRegistering($contry2char): false);

	
			
		// now detect if they are using a proxy
		$isProxy = $this->_getSpamModel()->isProxy('StopCountrySpam actionIndex', $this->_input);
		$isProxy = ($isProxy  != false ? $isProxy : "No Proxy Detected");
		
		
		if($isBlockedFromRegistering || ($isProxy != "No Proxy Detected"))
		{
			$options = XenForo_Application::get('options');		
			$ListingType = ($options->blackOrWhite == 1 ? "Black" : "White");			
	
			
			if (XenForo_Application::$versionId >= 1030000)
			{
				$longIpAddress = XenForo_Helper_Ip::getBinaryIp();
				$ipAddress = XenForo_Helper_Ip::convertIpBinaryToString($longIpAddress); 		
			}
			else
			{
				$longIpAddress = $this->_getLoginModel()->convertIpToLong();
				$ipAddress = long2ip($longIpAddress);
			}
			
			
			

			$logMsg = 'Via actionIndex() '.new XenForo_Phrase('sf_user_blocked_from_registering');
			
			
			if($isBlockedFromRegistering) 
			{
				$logMsg .= ($ListingType == "White" ? ", country not on white list: " : ",country on black list: ");
				$logMsg .= $contry2char;
			}
			
			if($isProxy != "No Proxy Detected") 
			{
				$logMsg .= ", Proxy detected";
			}
			
			
			
			// Store ip_address as text to see whats going on
			
			$logEvents = ($options->scsLogEvents == 1 ? true : false); 
			$dontLogDupUsername = ($options->scsdontLogDupName == 1 ? true : false);
			$dontLogDupEmail = ($options->scsdontLogDupEmail == 1 ? true : false);
			$dontLogDupIP = ($options->scsdontLogDupIP == 1 ? true : false);
			
			if ($logEvents)
			{
				
				$logThisEvent = true;
				$writer = XenForo_DataWriter::create('Tac_StopCountrySpam_DataWriter_Log');
					
				if(array_key_exists('username', $params["fields"] ))
				{
					$username = $responseView->params["fields"]["username"];
				}
				if(array_key_exists('uuid1', $params["fields"] ))
				{
					$username = $responseView->params["fields"]["uuid1"];
				}
				if(array_key_exists('email', $params["fields"] ))
				{
					$email = $responseView->params["fields"]["email"];
				}
				if(array_key_exists('uuid2', $params["fields"] ))
				{
					$email = $responseView->params["fields"]["uuid2"];
				}	
				
				
				
				if($username)
				{
					$writer->set('username', $username);
					$dupUsername = ($this->_getLogSCSLogModel()->getLogByUsername($username) ? true : false);
					if ($dupUsername && $dontLogDupUsername && ($username != '')){$logThisEvent = false;}				
				}
				if($email)
				{
					$writer->set('email', $email);
					$dupEmail = ($this->_getLogSCSLogModel()->getLogByEmail($email) ? true : false);
					if ($dupEmail && $dontLogDupIP && ($email != '')){$logThisEvent = false;}					 
				}		
						
				$dupIP = ($this->_getLogSCSLogModel()->getLogByIP($longIpAddress) ? true : false);			
				if ($dupIP && $dontLogDupIP){$logThisEvent = false;}
				
				
				// only log if we are recording duplicate entries
				if($logThisEvent && $contry2char && $jsonRequest && $jsonResponse)
				{
					$writer->set('log_date', XenForo_Application::$time);
					$writer->set('ip_address', $longIpAddress);
					$writer->set('log_type', 'Registration Blocked');
					$writer->set('listing_type', $ListingType);
					$writer->set('request_url', $jsonRequest);
					$writer->set('request_response', $jsonResponse);
					$writer->set('country_code_index', $countryCodeIndex);
					$writer->set('country_detected', $contry2char);
					$writer->set('message', $logMsg);
					$writer->set('proxy', $isProxy);
					$writer->save();	
				}
			}
			
			if ($options->countryBannedMsg == 0) 
			{		
				throw $this->responseException($this->responseError(
					new XenForo_Phrase('new_registrations_currently_not_being_accepted')
				));
			}
			
			else 
			{
				$viewParams = array();	
				return $this->responseView('', 'StopCountrySpam_BannedMsg', $viewParams);	
			}
			
			
		}
		return $responseView;
	}
	
	
	
	//over ride the register.. for bots that just send the params:
	
	
	
	public function actionRegister()
	{

		$users_ip = $_SERVER['REMOTE_ADDR']; 		
		$options = XenForo_Application::get('options');		
		$selectedCountries = $options->spamCountries;
		$ListingType = ($options->blackOrWhite == 1 ? "Black" : "White");
		$jsonRequest = str_replace('{$ip}', $users_ip, $options->jsonRequest);
		$countryCodeIndex = $options->countryCodeIndex;
		$isBlockedFromRegistering = false;
		$contry2char = "";
		
		try {
			
			$jsonResponse = file_get_contents($jsonRequest);
			
			$json = json_decode($jsonResponse,true);
			if($json == NULL)
			{	    		
	   	 		$jsonResponseIndexQuoteFix = preg_replace('/(\w+):/i', '"\1":', $jsonResponse);
	    		$json = json_decode($jsonResponseIndexQuoteFix,true);
			}
			
			
			
			/*
			* we also have to deal with nested indexes
			* nested indexes can be used in the format index1['index2']["index3"][index4]
			* this is a mixed format, but we may as well support, since supporting this will support pure/"correct" formats
			* and be lenient on user error.
			* For example, country['code'] is valid, as is country['code']['2digit'], as is country['code'][2digit]
			*/
			
			$isNested = strrpos($countryCodeIndex, "[");
			if ($isNested > 0) 
			{ 
				/* split this index1['index2']["index3"][index4]
				* into this: array ("index1","index2","index3","index4")
				* 1) strip out ',",] => index1[index2[index3[index4
				* 2) no brainer, split by [
				*/
				
				$stripOut = str_replace(array('"',  "'", "]", " " ), '',$countryCodeIndex);
        		$countryCodeIndexes = explode("[", $stripOut);       			
        		
        		
        		$nestSize = count($countryCodeIndexes);
        		
        		switch ($nestSize) {
				    case 0:
				        break;
				    case 1:
				        $contry2char = $json[$countryCodeIndexes[0]];
				        break;
				    case 2:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]];
				        break;
				    case 3:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]][$countryCodeIndexes[2]];
				        break;
				    case 4:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]][$countryCodeIndexes[2]][$countryCodeIndexes[3]];
				        break;
				}
			}					
			else if($countryCodeIndex == "" || $countryCodeIndex == "(none)" || $countryCodeIndex == "none"){
				$contry2char = $jsonResponse;
			}			
			else 
			{

				$contry2char = $json[$countryCodeIndex];
			}
		}
		catch (Exception $e) 
		{	
			return parent::actionRegister(); 	
	    // no need to do anything, if the JSON site is down we don't want to stop registration / throw up errors to the user	
		}	
		
		
		$isBlockedFromRegistering = $this->_getSpamModel()->getBlockedFromRegistering($contry2char);

	
		// now detect if they are using a proxy
		$isProxy = $this->_getSpamModel()->isProxy('StopCountrySpam actionRegister', $this->_input);
		$isProxy = ($isProxy  != false ? $isProxy : "No Proxy Detected");
		
		if($isBlockedFromRegistering || ($isProxy != "No Proxy Detected"))
		{
			
			
			/// this is the standard data, if foolbothoneypot is not installed / the bot just passes standard fields
			// since normal user wont get here, assume these are bots that just pass the standard fields	
			
			
			
			$data = $this->_input->filter(array(
				'username'   => XenForo_Input::STRING,
				'email'      => XenForo_Input::STRING,
				'timezone'   => XenForo_Input::STRING,
				'gender'     => XenForo_Input::STRING,
				'dob_day'    => XenForo_Input::UINT,
				'dob_month'  => XenForo_Input::UINT,
				'dob_year'   => XenForo_Input::UINT,
			));
			
			
			if (XenForo_Application::$versionId >= 1030000)
			{
				$longIpAddress = XenForo_Helper_Ip::getBinaryIp();
				$ipAddress = XenForo_Helper_Ip::convertIpBinaryToString($longIpAddress); 		
			}
			else
			{
				$longIpAddress = $this->_getLoginModel()->convertIpToLong();
				$ipAddress = long2ip($longIpAddress);
			}
			
			$username = $data['username'];
			$email = $data['email'];
	
	
			$options = XenForo_Application::get('options');		
			$ListingType = ($options->blackOrWhite == 1 ? "Black" : "White");	
		
			

			$logMsg = 'Direct actionRegister() '.new XenForo_Phrase('sf_user_blocked_from_registering');
			
			if($isBlockedFromRegistering) 
			{
				$logMsg .= ($ListingType == "White" ? ", country not on white list: " : ",country on black list: ");
				$logMsg .= $contry2char;
			}
			
			if($isProxy != "No Proxy Detected") 
			{
				$logMsg .= ", Proxy detected";
			}
			
				
			// Store ip_address as text to see whats going on
				
			$logEvents = ($options->scsLogEvents == 1 ? true : false); 
			$dontLogDupUsername = ($options->scsdontLogDupName == 1 ? true : false);
			$dontLogDupEmail = ($options->scsdontLogDupEmail == 1 ? true : false);
			$dontLogDupIP = ($options->scsdontLogDupIP == 1 ? true : false);
				
			if ($logEvents)
			{
					
				$logThisEvent = true;
				$writer = XenForo_DataWriter::create('Tac_StopCountrySpam_DataWriter_Log');
					
					
					
					
				if($username)
				{
					$writer->set('username', $username);
					$dupUsername = ($this->_getLogSCSLogModel()->getLogByUsername($username) ? true : false);
					if ($dupUsername && $dontLogDupUsername && ($username != '')){$logThisEvent = false;}				
				}
				if($email)
				{
					$writer->set('email', $email);
					$dupEmail = ($this->_getLogSCSLogModel()->getLogByEmail($email) ? true : false);
					if ($dupEmail && $dontLogDupIP && ($email != '')){$logThisEvent = false;}					 
				}		
							
				$dupIP = ($this->_getLogSCSLogModel()->getLogByIP($longIpAddress) ? true : false);			
				if ($dupIP && $dontLogDupIP){$logThisEvent = false;}
					
					
				// only log if we are recording duplicate entries
				if($logThisEvent)
				{
					$writer->set('log_date', XenForo_Application::$time);
					$writer->set('ip_address', $longIpAddress);
					$writer->set('log_type', 'Registration Blocked & Direct Params Sent - ');
					$writer->set('listing_type', $ListingType);
					$writer->set('request_url', $jsonRequest);
					$writer->set('request_response', $jsonResponse);
					$writer->set('country_code_index', $countryCodeIndex);
					$writer->set('country_detected', $contry2char);
					$writer->set('message', $logMsg);
					$writer->set('proxy', $isProxy);
					$writer->save();	
				}
			}
				
			if ($options->countryBannedMsg == 0) 
			{		
				throw $this->responseException($this->responseError(
					new XenForo_Phrase('new_registrations_currently_not_being_accepted')
				));
			}
			
			else 
			{
				$viewParams = array();	
				return $this->responseView('', 'StopCountrySpam_BannedMsg', $viewParams);	
			}
				
				
		}
			
		// if not needed, just clearer here
		if (!$isBlockedFromRegistering) 
		{
			$responseView = parent::actionRegister(); 	
			return $responseView;
		}
	}
	
	
	
	
	
	
	public function actionFacebook()
	{  // this is just duplicated, this should really be tidied up and put in Model where appropriate
	
		$responseView = parent::actionFacebook();
		
		$options = XenForo_Application::get('options');
		
		$faceBookStopCountry = ($options->faceBookStopCountry == 1 ? true : false);
			
		if (!$faceBookStopCountry) { return $responseView; }
				
		// we dont want to stop logging in, just registering
	
		// first, get the JSON response:
		// note, this wont work on a localhost testing environment (the IP address is 127.0.0.1)		
		
		$users_ip = $_SERVER['REMOTE_ADDR']; 		
		$options = XenForo_Application::get('options');		
		$selectedCountries = $options->spamCountries;
		$ListingType = ($options->blackOrWhite == 1 ? "Black" : "White");
		$jsonRequest = str_replace('{$ip}', $users_ip, $options->jsonRequest);
		$countryCodeIndex = $options->countryCodeIndex;
		$isBlockedFromRegistering = false;
		$contry2char = "";
		
		try {
			
			$jsonResponse = file_get_contents($jsonRequest);
			
			$json = json_decode($jsonResponse,true);
			if($json == NULL)
			{	    		
	   	 		$jsonResponseIndexQuoteFix = preg_replace('/(\w+):/i', '"\1":', $jsonResponse);
	    		$json = json_decode($jsonResponseIndexQuoteFix,true);
			}
			
			
			
	
			
			$isNested = strrpos($countryCodeIndex, "[");
			if ($isNested > 0) 
			{ 
				
				$stripOut = str_replace(array('"',  "'", "]", " " ), '',$countryCodeIndex);
        		$countryCodeIndexes = explode("[", $stripOut);       			
        		     		
        		$nestSize = count($countryCodeIndexes);
        		
        		switch ($nestSize) {
				    case 0:
				        break;
				    case 1:
				        $contry2char = $json[$countryCodeIndexes[0]];
				        break;
				    case 2:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]];
				        break;
				    case 3:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]][$countryCodeIndexes[2]];
				        break;
				    case 4:
				        $contry2char = $json[$countryCodeIndexes[0]][$countryCodeIndexes[1]][$countryCodeIndexes[2]][$countryCodeIndexes[3]];
				        break;
				}
			}					
			else if($countryCodeIndex == "" || $countryCodeIndex == "(none)" || $countryCodeIndex == "none"){
				$contry2char = $jsonResponse;
			}			
			else 
			{

				$contry2char = $json[$countryCodeIndex];
			}
		}
		catch (Exception $e) 
		{		
	    			$jsonResponse = 'No Response';
					$countryCodeIndex = 'XX';
					$contry2char = 'XX';
					$logMsg = $e->getMessage();
		}	
		
		
		$isBlockedFromRegistering = $this->_getSpamModel()->getBlockedFromRegistering($contry2char);

	
			
		// now detect if they are using a proxy
		$isProxy = $this->_getSpamModel()->isProxy('StopCountrySpam actionFacebook', $this->_input);
		$isProxy = ($isProxy  != false ? $isProxy : "No Proxy Detected");
		
		
		if($isBlockedFromRegistering || ($isProxy != "No Proxy Detected"))
		{

					
			$ListingType = ($options->blackOrWhite == 1 ? "Black" : "White");			
	
			
			if (XenForo_Application::$versionId >= 1030000)
			{
				$longIpAddress = XenForo_Helper_Ip::getBinaryIp();
				$ipAddress = XenForo_Helper_Ip::convertIpBinaryToString($longIpAddress); 		
			}
			else
			{
				$longIpAddress = $this->_getLoginModel()->convertIpToLong();
				$ipAddress = long2ip($longIpAddress);
			}
			
	
			$logMsg = 'Via actionFacebook() '.new XenForo_Phrase('sf_user_blocked_from_registering');
			
			if($isBlockedFromRegistering) 
			{
				$logMsg .= ($ListingType == "White" ? ", country not on white list: " : ",country on black list: ");
				$logMsg .= $contry2char;
			}
			
			if($isProxy != "No Proxy Detected") 
			{
				$logMsg .= ", Proxy detected";
			}
			
	
					
			// Store ip_address as text to see whats going on
			
			$logEvents = ($options->scsLogEvents == 1 ? true : false); 
			$dontLogDupUsername = ($options->scsdontLogDupName == 1 ? true : false);
			$dontLogDupEmail = ($options->scsdontLogDupEmail == 1 ? true : false);
			$dontLogDupIP = ($options->scsdontLogDupIP == 1 ? true : false);
			
			if ($logEvents)
			{
				
				$logThisEvent = true;
				$writer = XenForo_DataWriter::create('Tac_StopCountrySpam_DataWriter_Log');
					
				
				$username = ""; $email = "";  // we can't log username / email, since this is before they get set via FB

				
					
				$dupIP = ($this->_getLogSCSLogModel()->getLogByIP($longIpAddress) ? true : false);			
				if ($dupIP && $dontLogDupIP){$logThisEvent = false;}
				
				
				// only log if we are recording duplicate entries
				if($logThisEvent)
				{
					$writer->set('log_date', XenForo_Application::$time);
					$writer->set('ip_address', $longIpAddress);
					$writer->set('log_type', 'Registration Blocked via FaceBook');
					$writer->set('listing_type', $ListingType);
					$writer->set('request_url', $jsonRequest);
					$writer->set('request_response', $jsonResponse);
					$writer->set('country_code_index', $countryCodeIndex);
					$writer->set('country_detected', $contry2char);
					$writer->set('message', $logMsg);
					$writer->set('proxy', $isProxy);
					$writer->save();	
				}
			}
			
			if ($options->countryBannedMsg == 0) 
			{		
				throw $this->responseException($this->responseError(
					new XenForo_Phrase('new_registrations_currently_not_being_accepted')
				));
			}
			
			else 
			{
				$viewParams = array();	
				return $this->responseView('', 'StopCountrySpam_BannedMsg', $viewParams);	
			}
			
			
		}
		return $responseView;	
			
		
	}
	
	
	
	
	
	public function actionKeyUpdateSCS()
	{
		$options = XenForo_Application::get('options');
		$apiKey = $options->scsStopProxiesKey; // *3 Once again, update this option_name for your plugin
		$updated = $this->_getStopProxiesModel()->updateKey($this->_input, $apiKey, 'scsStopProxiesKey'); // This updates the key for 1st time use (no need to register)
		return $this->responseError("This page is not for public view");
	}		
	
	
	
	
	
	
	protected function _getStopProxiesModel()
	{
		return $this->getModelFromCache('Tac_StopCountrySpam_Model_StopProxies');
	}	
		
	
	protected function _getSpamModel()
	{
		return $this->getModelFromCache('Tac_StopCountrySpam_Model_Spam');
	}	
	
	protected function _getLoginModel()
	{
		return $this->getModelFromCache('XenForo_Model_Login');
	}
	
	protected function _getLogSCSLogModel()
	{
		return $this->getModelFromCache('Tac_StopCountrySpam_Model_Log');
	}

	
}