You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							188 lines
						
					
					
						
							3.6 KiB
						
					
					
				
			
		
		
	
	
							188 lines
						
					
					
						
							3.6 KiB
						
					
					
				<?php | 
						|
 | 
						|
namespace App\Classes; | 
						|
 | 
						|
use \Klein\Klein; | 
						|
 | 
						|
class Form { | 
						|
 | 
						|
	private $router; | 
						|
 | 
						|
	private $data = []; | 
						|
	private $resetLabel = ''; | 
						|
	private $submitLabel = 'Submit'; | 
						|
	private $errorKey = ''; | 
						|
 | 
						|
	public function __construct(Klein $router) | 
						|
	{ | 
						|
		$this->router = $router; | 
						|
		$this->router->service()->csrfToken = Session::token(); | 
						|
		$this->router->service()->form = $this; | 
						|
		$this->router->service()->injectView = '../app/views/form.php'; | 
						|
	} | 
						|
 | 
						|
	//-------------------------------------// | 
						|
 | 
						|
	public function addField(string $name, array $field): void | 
						|
	{ | 
						|
		// "name" => [ | 
						|
		// 	"label", | 
						|
		// 	"type",	   text, email, tel, password, radio, textarea, checkbox(?), comment | 
						|
		// 	"data",	   (for radio fields) [ 'value' => 'Label', 'value' => 'Label'] | 
						|
		// 	"rules",   (server side rules) | 
						|
		// 	"message", (server side error message) | 
						|
		// 	"pattern", (client sided rule) | 
						|
		// 	"title", | 
						|
		// ], | 
						|
 | 
						|
		$this->data[$name] = [ | 
						|
			$field[0] ?? '', | 
						|
			$field[1] ?? '', | 
						|
			$field[2] ?? '', | 
						|
			$field[3] ?? '', | 
						|
			$field[4] ?? '', | 
						|
			$field[5] ?? '', | 
						|
			$field[6] ?? '', | 
						|
		]; | 
						|
	} | 
						|
 | 
						|
	public function validated(array $submit = []): bool | 
						|
	{ | 
						|
		$result = false; | 
						|
 | 
						|
		if ($_SERVER['REQUEST_METHOD'] == 'POST') { | 
						|
 | 
						|
			$result = true; | 
						|
 | 
						|
			if (empty($submit)) { | 
						|
				$submit = $_POST; | 
						|
			} | 
						|
 | 
						|
			if (!Session::validateToken($submit)) { | 
						|
				$result = false; | 
						|
			} | 
						|
 | 
						|
			// Only check fields if CSRF token is valid | 
						|
			if ($result) { | 
						|
				// Check field rules | 
						|
				foreach ($this->data as $ruleName => $ruleValue) { | 
						|
 | 
						|
					$found = false; | 
						|
					$value = ''; | 
						|
					foreach ($submit as $submitName => $submitValue) { | 
						|
 | 
						|
						if ($ruleName == $submitName) { | 
						|
							$found = true; | 
						|
							$value = $submitValue; | 
						|
							break; | 
						|
						} | 
						|
 | 
						|
						if ($ruleValue[1] == 'comment') { | 
						|
							$found = true; | 
						|
							break; | 
						|
						} | 
						|
					} | 
						|
 | 
						|
					if (!$found || !$this->matchRule($ruleName, $value)) { | 
						|
						$this->errorKey = $ruleName; | 
						|
						$result = false; | 
						|
						break; | 
						|
					} | 
						|
				} | 
						|
			} | 
						|
 | 
						|
			// If unsuccessful, remember the form fields | 
						|
			if (!$result) { | 
						|
				foreach (array_keys($this->data) as $name) { | 
						|
					if ($name == 'captcha') { | 
						|
						continue; | 
						|
					} | 
						|
 | 
						|
					$this->router->service()->{$name} = $submit[$name] ?? ''; | 
						|
				} | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		Session::delete('captcha'); | 
						|
 | 
						|
		return $result; | 
						|
	} | 
						|
 | 
						|
	public function matchRule(string $key, string $value): bool | 
						|
	{ | 
						|
		// Get the rule(s) | 
						|
		$rule = $this->data[$key]; | 
						|
		$rules = explode('|', $rule[3]); | 
						|
 | 
						|
		if (array_search('required', $rules) !== false) { | 
						|
			if (empty($value)) { | 
						|
				return false; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		if (array_search('email', $rules) !== false) { | 
						|
			if (!filter_var($value, FILTER_VALIDATE_EMAIL)) { | 
						|
				return false; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		if (array_search('tel', $rules) !== false) { | 
						|
			if (!filter_var($value, FILTER_VALIDATE_REGEXP, [ | 
						|
				'options' => [ | 
						|
					'regexp' => '/^([0-9]{2}-?[0-9]{8})|([0-9]{3}-?[0-9]{7})$/', | 
						|
				] | 
						|
			])) { | 
						|
				return false; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		if (array_search('captcha', $rules) !== false) { | 
						|
			if (!Session::exists('captcha')) { | 
						|
				return false; | 
						|
			} | 
						|
			else if ($value != Session::get('captcha')) { | 
						|
				return false; | 
						|
			} | 
						|
		} | 
						|
 | 
						|
		return true; | 
						|
	} | 
						|
 | 
						|
	public function errorMessage(): string | 
						|
	{ | 
						|
		return $this->errorKey != '' ? $this->data[$this->errorKey][4] : ''; | 
						|
	} | 
						|
 | 
						|
	//-------------------------------------// | 
						|
 | 
						|
	public function getFields(): array | 
						|
	{ | 
						|
		return $this->data; | 
						|
	} | 
						|
 | 
						|
	public function getReset(): string | 
						|
	{ | 
						|
		return $this->resetLabel; | 
						|
	} | 
						|
 | 
						|
	public function getSubmit(): string | 
						|
	{ | 
						|
		return $this->submitLabel; | 
						|
	} | 
						|
 | 
						|
	public function setData(array $data): void | 
						|
	{ | 
						|
		$this->data = $data; | 
						|
	} | 
						|
 | 
						|
	public function setReset(string $resetLabel): void | 
						|
	{ | 
						|
		$this->resetLabel = $resetLabel; | 
						|
	} | 
						|
 | 
						|
	public function setSubmit(string $submitLabel): void | 
						|
	{ | 
						|
		$this->submitLabel = $submitLabel; | 
						|
	} | 
						|
 | 
						|
}
 | 
						|
 |