form/src/Form.php

193 lines
5.9 KiB
PHP
Raw Permalink Normal View History

2017-06-01 09:44:36 +00:00
<?php
namespace Krutush\Form;
use Krutush\Template\Html;
class Form {
private $method;
private $url;
private $elements = array();
private $name;
private $errors = array();
private $set = false;
2018-05-13 11:37:35 +00:00
private $csrfToken;
public static $csrfSession = '_form_token';
public static $csrfInput = "_token";
2017-06-01 09:44:36 +00:00
2018-05-07 12:11:15 +00:00
public function __construct(string $name, string $path, string $extention = null, bool $folder = true, array $sets = array()){
2017-06-01 09:44:36 +00:00
$this->name = $name;
2018-06-27 17:20:18 +00:00
$this->resetCsrf();
2017-06-01 09:44:36 +00:00
$tpl = new Html($path, $extention, $folder);
$tpl->set($name, $this)
2018-05-07 12:11:15 +00:00
->sets($sets)
2017-06-01 09:44:36 +00:00
->run('buffer');
return $this;
}
2018-06-27 17:20:18 +00:00
public function resetCsrf(){
if(session_status() == PHP_SESSION_NONE) session_start(); //TODO: create Krutsh\Session
if(isset($_SESSION[static::$csrfSession][$this->name])){
$this->csrfToken = $_SESSION[static::$csrfSession][$this->name];
}else{
$this->csrfToken = base64_encode(random_bytes(6));
$_SESSION[static::$csrfSession][$this->name] = $this->csrfToken;
}
}
2017-06-01 09:44:36 +00:00
public static function sanitize(array $data) : array{
$return = array();
foreach($data as $key => $value){
if(is_string($value))
$return[$key] = strip_tags(trim($value));
}
return $return;
}
public function valid(array $data) : bool{
$data = static::sanitize($data);
$this->set = true;
2018-05-13 11:37:35 +00:00
if(!isset($_SESSION[static::$csrfSession][$this->name]) || !isset($data[static::$csrfInput]) || $_SESSION[static::$csrfSession][$this->name] != $data[static::$csrfInput]){
$this->error('Formulaire expiré');
return false;
}
2017-06-01 09:44:36 +00:00
$valid = true;
foreach($this->elements as $element){
$value = isset($data[$element->name()]) ? $data[$element->name()] : null;
$return = $element->valid($value);
if($return !== true){
2018-06-27 17:20:18 +00:00
$this->error('Le champ '.$element->name().' est '.$return.'.', false);
2017-06-01 09:44:36 +00:00
$valid = false;
}else{
$element->value($value);
}
}
2018-05-13 11:37:35 +00:00
if($valid)
unset($_SESSION[static::$csrfSession][$this->name]);
2018-06-27 17:20:18 +00:00
2017-06-01 09:44:36 +00:00
return $valid;
}
2018-06-27 17:20:18 +00:00
public function error(string $error, bool $reset = true){
2018-04-27 11:46:50 +00:00
$this->errors[] = $error;
2018-06-27 17:20:18 +00:00
if($reset)
$this->resetCsrf();
2018-04-27 11:46:50 +00:00
}
2017-06-01 09:44:36 +00:00
public function name() : string{
return $this->name;
}
2018-04-27 11:46:50 +00:00
public function _start(string $more = '', string $method = 'post', string $url = null) : string{
2017-06-01 09:44:36 +00:00
if(!in_array($method, array('post', 'get')))
$method = 'post';
if($this->set == false){
$this->method = $method;
$this->url = $url;
}
2017-06-10 15:21:03 +00:00
$html = '<form method="'.$method.'" '.(isset($url) ? 'action="'.$url.'" ' : '').$more.'>';
2018-05-13 11:37:35 +00:00
$html .= '<input type="hidden" name="'.static::$csrfInput.'" value="'.$this->csrfToken.'">';
2017-06-10 15:21:03 +00:00
$html .= "
<script type=\"text/javascript\">
function SelectOther(source, other){
if(source.tagName == 'SELECT' && source.value == other){
source.style.display = 'none';
source.disabled = true;
var input = document.getElementsByName(source.name)[1];
input.style.display = '';
input.disabled = false;
input.value = source.value;
}else if(source.tagName == 'INPUT' && source.value.length == 0){
source.style.display = 'none';
source.disabled = true;
var select = document.getElementsByName(source.name)[0];
select.style.display = '';
select.disabled = false;
select.value = '';
}
}
</script>
";
return $html;
2017-06-01 09:44:36 +00:00
}
2018-04-27 11:46:50 +00:00
public function _end(string $more = '') : string{
2017-06-01 09:44:36 +00:00
return '</form '.$more.'>';
}
2018-04-27 11:46:50 +00:00
public function _errors(string $more = '') : string{
2017-06-01 09:44:36 +00:00
if(empty($this->errors))
return '';
$html = '<div class="errors" '.$more.'>';
foreach($this->errors as $error){
$html .= '<p>'.$error.'</p>';
}
return $html.'</div>';
}
2018-04-27 11:46:50 +00:00
public function _submit(string $name = null, string $more = '') : string{
2017-06-01 09:44:36 +00:00
return '<input type="submit" '.(isset($name) ? 'value="'.$name.'" ' : '').$more.'>';
}
2018-04-27 11:46:50 +00:00
function _input(string $name, bool $add = true) : Element{
2017-06-10 15:21:03 +00:00
if($add == false)
return new Input($name);
2017-06-01 09:44:36 +00:00
if($this->set == true){
$input = $this->get($name);
if(isset($input))
return $input;
}
$input = new Input($name);
$this->add($input);
return $input;
}
2018-04-27 11:46:50 +00:00
function _select(string $name, bool $add = true) : Element{
2017-06-10 15:21:03 +00:00
if($add == false)
return new Select($name);
2017-06-01 09:44:36 +00:00
if($this->set == true){
$input = $this->get($name);
if(isset($input))
return $input;
}
$input = new Select($name);
$this->add($input);
return $input;
}
2018-04-27 11:46:50 +00:00
function _textarea(string $name) : Element{
2017-06-01 09:44:36 +00:00
if($this->set == true){
$input = $this->get($name);
if(isset($input))
return $input;
}
$input = new TextArea($name);
$this->add($input);
return $input;
}
2017-06-10 15:21:03 +00:00
public function add(Element $thing){
2017-06-01 09:44:36 +00:00
if($this->set == false)
$this->elements[] = $thing;
}
2018-04-25 17:15:57 +00:00
public function get(string $name) : Element{
2017-06-01 09:44:36 +00:00
foreach($this->elements as $element){
if($element->name() == $name)
return $element;
}
return null;
}
public function values(bool $nullToEmpty = false) : array{
$values = array();
foreach($this->elements as $element){
$value = $element->get();
$values[$element->name()] = $nullToEmpty && !isset($value) ? '' : $value;
}
return $values;
}
}