diff --git a/src/Common/UiElement.php b/src/Common/UiElement.php
index f130a4c..e941c6d 100644
--- a/src/Common/UiElement.php
+++ b/src/Common/UiElement.php
@@ -177,8 +177,10 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
}
}
else if ( !is_numeric($key) ) {
- # will output something like
- $attributesList[] = strpos($value, '"') !== false ? "$key='$value'" : "$key=\"$value\"";
+ $value = htmlspecialchars($value);
+
+ # will output something like
+ $attributesList[] = "$key=\"$value\"";
}
else {
# will output something like
@@ -231,7 +233,7 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
public function html($set = null) {
if ($set !== null) {
$this->content = $set;
-
+
return $this;
}
@@ -285,8 +287,18 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
break;
case 'style' :
- foreach($value as $var => $val) {
- $this->css($var, $val);
+ if ( is_string($value) )
+ {
+ foreach(array_filter(explode(";", $value)) as $vars) {
+ list($key, $value) = explode(':', $vars);
+
+ $this->css($key, $value);
+ }
+ }
+ elseif ( is_array($value) ) {
+ foreach($value as $var => $val) {
+ $this->css($var, $val);
+ }
}
break;
diff --git a/src/Component/UiPopup.php b/src/Component/UiPopup.php
index e7a152f..248652a 100644
--- a/src/Component/UiPopup.php
+++ b/src/Component/UiPopup.php
@@ -14,7 +14,7 @@ class UiPopup extends UiElement implements Extension {
public string $tag = "div";
public array $attributes = [
- 'class' => 'ui-popup',
+ 'class' => 'ui-popup',
];
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
diff --git a/src/Form/UiForm.php b/src/Form/UiForm.php
index 5d5b5e2..aba53b1 100644
--- a/src/Form/UiForm.php
+++ b/src/Form/UiForm.php
@@ -54,7 +54,7 @@ class UiForm extends UiElement implements Extension {
public function buildHtml(string $method = "get", string $name = "", string $action = "", array $attributes = []) : string
{
$method = strtolower($method);
-
+
$this->option('tag-type', 'single');
@@ -66,11 +66,23 @@ class UiForm extends UiElement implements Extension {
$this->attributes([ 'method' => $method, 'action' => $action ] + $attributes);
if ( $method !== "get" ) {
- $this->append( ( new UiHidden() )->attributes([ 'name' =>"picea-ui-form[$name]", 'value' => md5( $name . microtime() ) ]) );
+ $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,
+ ]));
$this->attributes([ 'enctype' => "multipart/form-data" ]);
}
-
+
return $this->render() . PHP_EOL;
}
}
\ No newline at end of file
diff --git a/src/Form/UiInput.php b/src/Form/UiInput.php
index 78b507b..d3812ff 100644
--- a/src/Form/UiInput.php
+++ b/src/Form/UiInput.php
@@ -43,7 +43,7 @@ class UiInput extends UiElement implements Extension {
}
if ($attributes['class'] ?? false) {
- $attributes['class'] = implode(" ", array_merge((array) $attributes['class'], (array) $this->attributes['class']));
+ $attributes['class'] .= " {$this->attributes['class']}";
unset($this->attributes['class']);
}
diff --git a/src/Form/UiTextarea.php b/src/Form/UiTextarea.php
index 1cfc674..c7c8b42 100644
--- a/src/Form/UiTextarea.php
+++ b/src/Form/UiTextarea.php
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiTextarea extends UiInput {
- public string $token = "ui.textarea";
+ public array $tokens = [ "ui.textarea", "ui.textarea.raw" ];
public string $tag = "textarea";
@@ -14,8 +14,27 @@ class UiTextarea extends UiInput {
public array $options = [];
+ protected bool $echoRaw = false;
+
+ public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
+ {
+ if ($token === 'ui.textarea.raw') {
+ $this->echoRaw = true;
+ }
+
+ return sprintf("echoRaw(%s)->buildHtml($arguments) ?>", $this->echoRaw ? 'true' : 'false');
+ }
+
+
protected function setValue($value) : void
{
- $this->html($value);
+ $this->echoRaw ? $this->html($value) : $this->text($value);
+ }
+
+ public function echoRaw(bool $set) : self
+ {
+ $this->echoRaw = $set;
+
+ return $this;
}
}
diff --git a/src/Method/Form.php b/src/Method/Form.php
index 256e0ef..e1796ec 100644
--- a/src/Method/Form.php
+++ b/src/Method/Form.php
@@ -32,22 +32,6 @@ class Form implements Extension {
$context->pushFunction("form", [ $this, 'formClass' ]);
}
- public function form_csrf(string $field, string $value) {
- $values = $this->session("View.form.csrf.$field") ?: [];
-
- # keeps 20 (from config) latest CSRF key for this form into session,
- # allowing more than one tab opened and preventing information loss
- if ( count($values) >= 20 ) {
- #array_shift($values);
- }
-
- $values[] = $value;
-
- $this->session("View.form.csrf.$field", $values);
-
- return $value;
- }
-
public function formClass(FormInterface $form, ? FormContext $formContext = null) : FormHandler
{
return new FormHandler($this->request, $form, $formContext);
diff --git a/src/Method/FormHandler.php b/src/Method/FormHandler.php
index ba8bab7..e6210e7 100644
--- a/src/Method/FormHandler.php
+++ b/src/Method/FormHandler.php
@@ -5,8 +5,11 @@ namespace Picea\Ui\Method;
use Psr\Http\Message\ServerRequestInterface;
class FormHandler {
+
public bool $sent = false;
+ public bool $validateCsrfToken = true;
+
public ? bool $executionStatus = null;
public FormContext $context;
@@ -38,7 +41,20 @@ class FormHandler {
{
if ( false !== $this->context->formSent = $this->sent ) {
if ( $this->context->formName ?? false ) {
- $this->sent = $this->context->formSent = (bool) ( $this->request->getParsedBody()['picea-ui-form'][$this->context->formName] ?? false );
+ $sent = false;
+
+ $token = $this->context->{'picea-ui-form'}[$this->context->formName] ?? false;
+
+ if ( $token ) {
+ if ($this->validateCsrfToken) {
+ $sent = in_array($token, $_SESSION["picea-ui.form:{$this->context->formName}"] ?? []);
+ }
+ else {
+ $sent = (bool) $token;
+ }
+ }
+
+ $this->sent = $this->context->formSent = $sent;
}
}
}
@@ -50,8 +66,6 @@ class FormHandler {
if ( $this->sent ) {
if ( $this->form->validate($this->context) ) {
$this->executionStatus = $this->form->execute($this->context);
-
- $this->context->formExecuted = true;
}
}
}