picea-ui/src/Form/UiForm.php
2025-10-15 15:01:20 +00:00

109 lines
3.0 KiB
PHP

<?php
namespace Picea\Ui\Form;
use Picea\Ui\Common\UiElement,
Picea\Extension\Extension,
Picea\Extension\ExtensionTrait;
class UiForm extends UiElement implements Extension {
use ExtensionTrait;
public string $defaultMethod = "get";
public array $token = [ "ui:form", "ui:endform", "ui:/form" ];
public array $attributes = [
'class' => 'ui-form',
];
public function __construct(
public string $tag = "form",
public bool $enctype = true,
public bool $csrf = true,
) {}
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token, array $options = []) : string
{
$constructor = [];
switch($token) {
case 'ui.endform': # bw compat
case 'ui:endform':
case 'ui:/form':
return "</form>";
}
if (in_array('no-enctype', $options)) {
$constructor[] = "enctype: false";
}
if (in_array('no-csrf', $options)) {
$constructor[] = "csrf: false";
}
if (in_array('get', $options)) {
$method = "get";
}
elseif (in_array('post', $options)) {
$method = "post";
}
elseif (in_array('put', $options)) {
$method = "put";
}
elseif (in_array('delete', $options)) {
$method = "delete";
}
elseif (in_array('patch', $options)) {
$method = "patch";
}
$method ??= $this->defaultMethod;
$opt = var_export($options, true);
$constructor = implode(',', $constructor);
return "<?php echo ( new \\" . static::class . "($constructor) )->buildHtml('$method', $arguments) ?>";
}
public function buildHtml(string $method = "get", string $name = "", string $action = "", array $attributes = []) : string
{
# Method passed in arguments take precedents over options
$method = strtolower($attributes['method'] ?? $method);
$this->option('tag-type', 'single');
if ($attributes['class'] ?? false) {
$attributes['class'] .= " {$this->attributes['class']}";
unset($this->attributes['class']);
}
$this->attributes([ 'action' => $action, 'method' => $method, ] + $attributes);
if ( $method !== "get" ) {
if ($this->csrf) {
$token = md5($name . microtime());
$key = "picea-ui:form:{$name}";
if (count($_SESSION[$key] ?? []) > 100) {
array_shift($_SESSION[$key]);
}
$_SESSION[$key][] = $token;
$this->append((new UiHidden())->attributes([
'name' => "picea-ui-form[$name]",
'value' => $token,
]));
}
if ($this->enctype) {
$this->attributes([ 'enctype' => "multipart/form-data" ]);
}
}
return $this->render() . PHP_EOL;
}
}