<?php namespace HashOver;// Copyright (C) 2015-2021 Jacob Barkdull// This file is part of HashOver.//// HashOver is free software: you can redistribute it and/or modify// it under the terms of the GNU Affero General Public License as// published by the Free Software Foundation, either version 3 of the// License, or (at your option) any later version.//// HashOver is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Affero General Public License for more details.//// You should have received a copy of the GNU Affero General Public License// along with HashOver.  If not, see <http://www.gnu.org/licenses/>.class FormData{	protected $setup;	protected $locale;	protected $spamCheck;	protected $cookies;	protected $referer;	public $data = array ();	public $remoteAccess = false;	public $file;	public $replyTo;	public $viaAJAX = false;	// Fake inputs used as spam trap fields	protected $trapFields = array (		'summary',		'age',		'lastname',		'address',		'zip'	);	public function __construct (Setup $setup, Cookies $cookies)	{		// Store parameters as properties		$this->setup = $setup;		// Instantiate various classes		$this->locale = new Locale ($setup);		$this->spamCheck = new SpamCheck ($setup);		$this->cookies = $cookies;		// Use POST or GET based on whether request is for JSONP		$request = isset ($_GET['jsonp']) ? $_GET : $_POST;		// Get regular expression escaped admin path		$admin_path = preg_quote ($this->setup->getHttpPath ('admin'), '/');		// Attempt to get referer		$referer = Misc::getArrayItem ($_SERVER, 'HTTP_REFERER');		// Set status		if (isset ($request['status'])) {			$this->data['status'] = $this->forceUTF8 ($request['status']);		}		// Set name		if (isset ($request['name'])) {			$this->data['name'] = $this->forceUTF8 ($request['name']);		}		// Set password		if (isset ($request['password'])) {			$this->data['password'] = $this->forceUTF8 ($request['password']);		}		// Set e-mail address		if (isset ($request['email'])) {			$this->data['email'] = $this->forceUTF8 ($request['email']);		}		// Set website URL		if (isset ($request['website'])) {			$this->data['website'] = $this->forceUTF8 ($request['website']);		}		// Set comment		if (isset ($request['comment'])) {			$this->data['comment'] = $this->forceUTF8 ($request['comment']);		}		// Set indicator of remote access		if (isset ($request['remote-access'])) {			$this->remoteAccess = true;		}		// Get comment file		if (isset ($request['file'])) {			$this->file = $request['file'];		}		// Get reply comment file		if (isset ($request['reply-to'])) {			$this->replyTo = $request['reply-to'];		}		// Set indicator of AJAX requests		if (isset ($request['ajax'])) {			$this->viaAJAX = true;		}		// Check if we're coming from an admin page		if (preg_match ('/' . $admin_path . '/i', $referer)) {			// If so, use it as the kickback URL			$this->referer = $_SERVER['HTTP_REFERER'];		} else {			// If not, check if posting from remote domain			if ($this->remoteAccess === true) {				// If so, use absolute path				$this->referer = $setup->pageURL;			} else {				// If not, use relative path				$this->referer = $setup->filePath;			}			// Add URL queries to kickback URL			if (!empty ($setup->urlQueries)) {				$this->referer .= '?' . $setup->urlQueries;			}		}	}	// Force a string to UTF-8 encoding and acceptable character range	protected function forceUTF8 ($string)	{		$string = mb_convert_encoding ($string, 'UTF-16', 'UTF-8');		$string = mb_convert_encoding ($string, 'UTF-8', 'UTF-16');		$string = preg_replace ('/[^\x{0009}\x{000A}\x{000D}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u', '?', $string);		return trim ($string, " \r\n\t");	}	// Sets header to redirect user back to the previous page	public function kickback ($anchor = 'comments')	{		header ('Location: ' . $this->referer . '#' . $anchor);	}	// Displays message to visitor, via AJAX or redirect	public function displayMessage ($locale, $error = false)	{		// Message type as string		$message_type = ($error === true) ? 'error' : 'message';		// Get message text from locales if it exists		if (!empty ($this->locale->text[$locale])) {			$locale = $this->locale->text[$locale];		}		// Check if request is not over an AJAX request		if ($this->viaAJAX !== true) {			// If so, set cookie to specified message			$this->cookies->set ($message_type, $locale);			// And redirect user to previous page			return $this->kickback ('hashover-form-section');		}		// Otherwise, display JSON for JavaScript frontend		echo Misc::jsonData (array (			'message' => $locale,			'type' => $message_type		));	}	// Checks user IP against spam databases	public function checkForSpam ($mode = 'javascript')	{		// Treat JSON mode as JavaScript mode		if ($mode === 'json') {			$mode = 'javascript';		}		// Block user if they fill any trap fields		foreach ($this->trapFields as $name) {			if ($this->setup->getRequest ($name)) {				throw new \Exception ('You are blocked!');			}		}		// Check user's IP address against local blocklist		if ($this->spamCheck->checkList () === true) {			throw new \Exception ('You are blocked!');		}		// Whether to check for spam in current mode		if ($this->setup->spamCheckModes === $mode		    or $this->setup->spamCheckModes === 'both')		{			// Check user's IP address against local or remote database			if ($this->spamCheck->{$this->setup->spamDatabase}() === true) {				throw new \Exception ('You are blocked!');			}			// Throw any error message as exception			if (!empty ($this->spamCheck->error)) {				throw new \Exception ($this->spamCheck->error);			}		}	}}