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; |
|
} |
|
|
|
}
|
|
|