5 Commits
58 changed files with 754 additions and 88 deletions

No files matched your search

+127
View File
@@ -0,0 +1,127 @@
# Picea UI
Welcome to the `picea-ui` documentation.
This quick documentation will guide you through the use of the form system, every available
UI elements and how to add customs one and individual components.
Mostly everything you need to build and process form is available in this package.
The first part is most input callable as a widget :
```
{% ui:text "fullname", "John Doe" %}
```
Current input support is :
```php
- Input (string $source, array $attributes = [], array $options = [])
- Checkbox (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Color (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Date (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Datetime (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Email (string $name, mixed $value = null, array $attributes = [], array $options = [])
- File (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Hidden (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Image (string $source, array $attributes = [], array $options = [])
- Numeric (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Password (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Radio (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Range (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Search (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Select (string $name, array $list, mixed $value = null, array $attributes = [], bool $strictComparison = true)
- Tel (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Text (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Textarea (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Time (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Url (string $name, mixed $value = null, array $attributes = [], array $options = [])
- Week (string $name, mixed $value = null, array $attributes = [], array $options = [])
```
**[PICEA]** So, using this code:
```html
{% ui:form.post "user.save", current_url() %}
<div class="field fullname">
<label>Full name</label>
{% ui:text "fullname", $user->fullname, [ 'required' => 'required' ] %}
</div>
<div class="field email">
<label>Email address</label>
{% ui:text "email", $user->email %}
</div>
<div class="field job">
<label>Have a job</label>
<label>{% ui:radio "job", 'yes', [], [ 'value' => $entity->job ] %} Yes</label>
<label>{% ui:radio "job", 'no', [], [ 'value' => $entity->job ] %} No</label>
</div>
<div class="field role">
<label>Role</label>
{% ui:select "role", [ 'user' => "User", 'moderator' => "Moderator", 'admin' => "Admin" ], $user->role, [ 'required' => 'required' ] %}
</div>
<button type="submit">Save</button>
{% ui:endform %}
```
**[HTML]** Would render as such:
```html
<form class="ui-form" method="post" action="http://127.0.0.1/" enctype="multipart/form-data">
<input class="ui-hidden" type="hidden" name="picea-ui-form[user.save]" value="617fb40f1999db63fbd0b4f680a77750">
<div class="field fullname">
<label>Full name</label>
<input class="ui-text" type="text" value="" name="fullname" required="required">
</div>
<div class="field email">
<label>Email address</label>
<input class="ui-text" type="text" value="" name="email">
</div>
<div class="field job">
<label>Have a job</label>
<label><input class="ui-radio" type="radio" value="yes" name="job"> Yes</label>
<label><input class="ui-radio" type="radio" value="no" name="job"> No</label>
</div>
<div class="field role">
<label>Role</label>
<select class="ui-select" name="role" required="required">
<option value="user">User</option>
<option value="moderator">Moderator</option>
<option value="admin">Admin</option>
</select>
</div>
<button type="submit">Save</button>
</form>
```
## Use your forms in controller
Forms can be used to handle how your data is handled, from loading (get) to processing (post).
The process is as simple as defining a Form, implementing FormInterface :
```php
interface FormInterface
{
public function initialize(FormContextInterface $context) : void;
public function validate(FormContextInterface $context) : bool;
public function execute(FormContextInterface $context);
}
```
`initialize` is called directly on `form()` method call.
`validate` will be called if the request's method is either `post`, `put`, `patch` or `delete`, which implies **adding** / **editing** / **deleting**.
`execute` will finally launch only if `validate` returns `true`. This is usually where you want to **save** / **destroy** your entities.
+13
View File
@@ -0,0 +1,13 @@
# `ui:checkbox` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:radio` component, which itself extends `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-checkbox"`
- `'type' => "checkbox"`
and will typically be rendered such as :
```html
<input class="ui-checkbox" type="checkbox" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:color` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-color"`
- `'type' => "color"`
and will typically be rendered such as :
```html
<input class="ui-color" type="color" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:date` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-date"`
- `'type' => "date"`
and will typically be rendered such as :
```html
<input class="ui-date" type="date" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:datetime` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-datetime"`
- `'type' => "datetime-local"`
and will typically be rendered such as :
```html
<input class="ui-datetime" type="datetime-local" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:email` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-email"`
- `'type' => "email"`
and will typically be rendered such as :
```html
<input class="ui-email" type="email" value="" name="">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:file` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-file"`
- `'type' => "file"`
and will typically be rendered such as :
```html
<input class="ui-file" type="file" value="" name="">
```
+18
View File
@@ -0,0 +1,18 @@
# `ui:form` / `ui:form.get` / `ui:form.post` (string $method = "get", string $name = "", string $action = "", array $attributes = [])
A version exists also for unsupported methods (as of HTML5) on forms `ui:form.put` / `ui:form.patch` / `ui:form.delete`, which
could find a use within a Javascript environment.
The following attributes are assigned by this extension :
- `'class' => "ui-form"`
- `'enctype' => "multipart/form-data"`
- `'method' => "get|post|put|patch|delete"`
and will typically be rendered such as :
```html
<form class="ui-form" enctype="multipart/form-data" action="$action" method="$method">
<input class="ui-hidden" type="hidden" name="picea-ui-form[$name]" value="{ random md5 hash }">
</form>
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:hidden` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-hidden"`
- `'type' => "hidden"`
and will typically be rendered such as :
```html
<input class="ui-hidden" type="hidden" value="" name="">
```
+12
View File
@@ -0,0 +1,12 @@
# `ui:image` (string $source, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-image"`
and will typically be rendered such as :
```html
<img class="ui-image" src="$source">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:input` (string $name, mixed $value = null, array $attributes = [], array $options = [])
This is small
The following attributes are assigned by this extension :
- `'class' => "ui-input"`
and will typically be rendered such as :
```html
<input class="ui-input" type="input" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:numeric` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-numeric"`
- `'type' => "numeric"`
and will typically be rendered such as :
```html
<input class="ui-numeric" type="numeric" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:password` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-password"`
- `'type' => "password"`
and will typically be rendered such as :
```html
<input class="ui-password" type="password" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:radio` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-radio"`
- `'type' => "radio"`
and will typically be rendered such as :
```html
<input class="ui-radio" type="radio" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:range` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-range"`
- `'type' => "range"`
and will typically be rendered such as :
```html
<input class="ui-range" type="range" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:search` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-search"`
- `'type' => "search"`
and will typically be rendered such as :
```html
<input class="ui-search" type="search" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:select` (string $name, array $list, $value = null, array $attributes = [], bool $strictComparison = true)
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-select"`
- `'type' => "select"`
and will typically be rendered such as :
```html
<input class="ui-select" type="select" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:tel` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-tel"`
- `'type' => "tel"`
and will typically be rendered such as :
```html
<input class="ui-tel" type="tel" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:text` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-text"`
- `'type' => "text"`
and will typically be rendered such as :
```html
<input class="ui-text" type="text" value="$value" name="$name">
```
+12
View File
@@ -0,0 +1,12 @@
# `ui:textarea` / `ui:textarea.raw` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`. This extension also comes with a raw modifier which skips the escaping.
The following attributes are assigned by this extension :
- `'class' => "ui-textarea"`
and will typically be rendered such as :
```html
<textarea class="ui-textarea" name="$name">$value</textarea>
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:time` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-time"`
- `'type' => "time"`
and will typically be rendered such as :
```html
<input class="ui-time" type="time" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:url` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-url"`
- `'type' => "url"`
and will typically be rendered such as :
```html
<input class="ui-url" type="url" value="$value" name="$name">
```
+13
View File
@@ -0,0 +1,13 @@
# `ui:week` (string $name, mixed $value = null, array $attributes = [], array $options = [])
Built on top of `ui:input`.
The following attributes are assigned by this extension :
- `'class' => "ui-week"`
- `'type' => "week"`
and will typically be rendered such as :
```html
<input class="ui-week" type="week" value="$value" name="$name">
```
+107
View File
@@ -0,0 +1,107 @@
# `form`(FormInterface $form, ? FormContext $formContext = null) : FormHandler
The `form()` method will process a form in three steps :
1. `initialize(FormContextInterface $context)` is first called on form processing.
2. `validate(FormContextInterface $context) : bool` will execute on POST. If you define a name to the form, it will match the one found in the POST (`picea-ui-form[$context->name]`) ; if the form is not the target, it will be skipped. Also, if an error si found within the message list, the method will return `false`.
3. `execute(FormContextInterface $context)` is the last method to run, which is usually where you save your entity and finilize your messages. The return value is accessible from the `formHandler` which `form()` returns.
**[PHP]** So, using this code:
in */app/controller/user.php*
```php
form(new \MyApp\Form\User\Create());
```
*/app/form/create.php*
```php
<?php
namespace MyProject\Form;
use MyProject\{ Lib, Entity };
use Picea\Ui\Method\{ FormContextInterface, Message\ErrorMessage };
use Psr\Http\Message\ServerRequestInterface;
use function MyProject\View\{ lang };
class Create implements \Picea\Ui\Method\FormInterface {
public function initialize(FormContextInterface $context) : void
{
$this->user = new Entity\User();
# $context->{varname} will be populated by $_POST data.
$this->user = (string) $context->fullname;
}
public function validate(FormContextInterface $context) : bool
{
if ( strlen($this->user) < 3 ) {
# This won't allow `execute` to run because of the error message.
$context->pushMessage(Lib\Message::generateError(
lang("form.error.provide_fullName")
));
}
return $context->valid();
}
public function execute(FormContextInterface $context) : void
{
# Saving a new user here
Entity\User::repository()->save($this->user);
$context->pushMessage(Lib\Message::generateSuccess(
lang("form.save")
));
}
}
```
which implements this interface :
```php
interface FormInterface
{
public function initialize(FormContextInterface $context) : void;
public function validate(FormContextInterface $context) : bool;
public function execute(FormContextInterface $context);
}
```
Would yield the same result such as:
```php
true
true
```
Trying to access either variable before `execute` is called will return `null`.
## `FormContext` object
`__construct(ServerRequestInterface $request, ? string $formName = null)`
Creating a form context manually allows to define the formName, which is essential if you want to use the
Cross-Scripting Request Forgery (CSRF).
It is populated with either $_POST or request's body which is json_decode. A property called `files` is also populated from PSR's `$request->getUploadedFiles()`.
It's `valid() : bool` method called into a form `validate()` function is first checking every message which were pushed into, using `pushMessage(FormMessage $message)`, and returns false if an error message is found in the list.
### Retrieve a form execution status / value
There is two ways to get the execution status (from the `execute` return value):
```php
$formContext = new \Picea\Ui\Method\FormContext($request, 'form.user_create');
$form = form(new \MyProject\Form\User\Create(), $formContext);
if ($formContext->formExecuted) {
echo $form->executionStatus;
echo $formContext->formExecutionStatus;
}
```
+8
View File
@@ -0,0 +1,8 @@
# `ui:popup` (string $name, array $variables = [], array $options = [])
The following attributes are assigned by this extension :
and will typically be rendered such as (directly inside an opening tag) :
```html
ui-popup='{ "name":$name,"vars":{$variables},"options":{$options} }'
```
+10 -11
View File
@@ -26,9 +26,9 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
* tag-type single Only render a single tag. Cannot contains any childrens
* force-tag-open tag Control the way the opening tag is rendered
* force-tag-close tag-close " " " " closing " " "
* no-attr Attributes will not be rendered
* no-id ID is not automatically given (* may be removed *)
* escape-tag-end If you need to echo the Node inside another string, it may be useful to escape the "/" char using "\/"
* no-attr true Attributes will not be rendered
* no-id true ID is not automatically given (* may be removed *)
* escape-tag-end true If you need to echo the Node inside another string, it may be useful to escape the "/" char using "\/"
*/
public array $options = [];
@@ -148,7 +148,7 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
return $this;
}
public function option(string $var, $value = 1) : self
public function option(string $var, mixed $value = true) : self
{
$this->options[$var] = $value;
@@ -200,14 +200,14 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
}
}
if ( in_array('no-tag', $this->options, true) ) {
if ( $this->options['no-tag'] ?? false ) {
return $this->content . $content;
}
else {
$compiledAttributes = (count($attributesList) && ! in_array('no-attr', $this->options, true) ? " " . implode(" ", $attributesList) : "");
$compiledAttributes = $this->options['no-attr'] ?? false ? "" : " " . implode(" ", $attributesList);
# Force the node to contain a certain opening tag (php is a good example)
if ( in_array('force-tag-open', $this->options, true) ) {
if ( $this->options['force-tag-open'] ?? false ) {
$opentag = $this->options['force-tag-open'] . $compiledAttributes;
}
else {
@@ -219,11 +219,11 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
$closetag = "";
}
}
elseif ( in_array('force-tag-close', $this->options, true) ) {
elseif ( $this->options['force-tag-close'] ?? false ) {
$closetag = $this->options['force-tag-close'];
}
else {
$closetag = $this->tag ? "<" . (in_array('escape-tag-end', $this->options) ? "\/" : "/" ) . "{$this->tag}>" : "";
$closetag = $this->tag ? "<" . ( $this->options['escape-tag-end'] ?? false ? "\/" : "/" ) . "{$this->tag}>" : "";
}
return $opentag . $this->content . $content . $closetag;
@@ -242,7 +242,7 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
public function text(?string $set = null) {
if ($set !== null) {
$this->content = htmlspecialchars( $set, ENT_NOQUOTES );
$this->content = htmlspecialchars( $set, \ENT_NOQUOTES );
return $this;
}
@@ -260,7 +260,6 @@ class UiElement implements \ArrayAccess, \Iterator, \JsonSerializable {
return $this->insert( static::INSERT_MODE_PREPEND, ...( is_array($arguments) ? array_reverse($arguments) : $arguments) );
}
protected function insert(int $mode, ...$elements) : self
{
foreach($elements as $item) {
+2 -2
View File
@@ -9,7 +9,7 @@ use Picea\Extension\ExtensionTrait;
class UiMessage extends UiElement implements Extension {
use ExtensionTrait;
public string $token = "ui.message";
public string $token = "ui:message";
public string $tag = "input";
@@ -17,7 +17,7 @@ class UiMessage extends UiElement implements Extension {
'class' => 'ui-message',
];
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string
{
return "";
}
+4 -4
View File
@@ -9,7 +9,7 @@ use Picea\Extension\ExtensionTrait;
class UiPopup extends UiElement implements Extension {
use ExtensionTrait;
public string $token = "ui.popup";
public string $token = "ui:popup";
public string $tag = "div";
@@ -17,14 +17,14 @@ class UiPopup extends UiElement implements Extension {
'class' => 'ui-popup',
];
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string
{
return "<?php echo 'ui-popup=\"' . ( new \\" . static::class . "() )->buildAttributes($arguments) . '\"' ?>";
}
public function buildAttributes(string $name, array $variables = [], $options = []) : string
public function buildAttributes(string $name, array $variables = [], array $options = []) : string
{
return htmlentities(json_encode([ "name" => $name, "vars" => $variables, "options" => $options ], JSON_HEX_APOS | JSON_HEX_QUOT), ENT_QUOTES, 'UTF-8');
return htmlentities(json_encode([ "name" => $name, "vars" => $variables, "options" => $options ], JSON_HEX_APOS | JSON_HEX_QUOT), \ENT_QUOTES, 'UTF-8');
}
}
+129
View File
@@ -0,0 +1,129 @@
<?php
namespace Picea\Ui\Form;
use Picea\Extension\Extension;
use Picea\Extension\ExtensionTrait;
use Picea\Ui\Common\UiElement;
use Picea\Ui\Component\UiMessage;
use Picea\Ui\Component\UiPopup;
class Ui extends UiElement implements Extension {
use ExtensionTrait;
public string $token = "ui";
protected /* ? mixed */ $value;
protected string $name;
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string
{
$opt = $context->tokenOptions($token);
switch(true) {
case in_array('checkbox', $opt):
$input = new UiCheckbox();
break;
case in_array('color', $opt):
$input = new UiColor();
break;
case in_array('date', $opt):
$input = new UiDate();
break;
case in_array('datetime', $opt):
$input = new UiDatetime();
break;
case in_array('email', $opt):
$input = new UiEmail();
break;
case in_array('file', $opt):
$input = new UiFile();
break;
case in_array('form', $opt):
case in_array('endform', $opt):
$input = new UiForm();
break;
case in_array('hidden', $opt):
$input = new UiHidden();
break;
case in_array('image', $opt):
$input = new UiImage();
break;
case in_array('input', $opt):
$input = new UiInput();
break;
case in_array('numeric', $opt):
$input = new UiNumeric();
break;
case in_array('password', $opt):
$input = new UiPassword();
break;
case in_array('radio', $opt):
$input = new UiRadio();
break;
case in_array('range', $opt):
$input = new UiRange();
break;
case in_array('search', $opt):
$input = new UiSearch();
break;
case in_array('select', $opt):
$input = new UiSelect();
break;
case in_array('tel', $opt):
$input = new UiTel();
break;
case in_array('text', $opt):
$input = new UiText();
break;
case in_array('textarea', $opt):
$input = new UiTextarea();
break;
case in_array('time', $opt):
$input = new UiText();
break;
case in_array('url', $opt):
$input = new UiUrl();
break;
case in_array('week', $opt):
$input = new UiWeek();
break;
case in_array('popup', $opt):
$input = new UiPopup();
break;
case in_array('message', $opt):
$input = new UiMessage();
break;
}
if (empty($input)) {
throw new \Exception("Missing token ? $token");
}
return $input->parse($context, $arguments, $token);
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiCheckbox extends UiRadio {
public string $token = "ui.checkbox";
public string $token = "ui:checkbox";
public array $attributes = [
'class' => "ui-checkbox",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiColor extends UiInput {
public string $token = "ui.color";
public string $token = "ui:color";
public array $attributes = [
'class' => "ui-color",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiDate extends UiInput {
public string $token = "ui.date";
public string $token = "ui:date";
public array $attributes = [
'class' => "ui-date",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiDatetime extends UiInput {
public string $token = "ui.datetime";
public string $token = "ui:datetime";
public array $attributes = [
'class' => "ui-datetime",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiEmail extends UiInput {
public string $token = "ui.email";
public string $token = "ui:email";
public array $attributes = [
'class' => "ui-email",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiFile extends UiInput {
public string $token = "ui.file";
public string $token = "ui:file";
public array $attributes = [
'class' => "ui-file",
+27 -23
View File
@@ -11,7 +11,7 @@ class UiForm extends UiElement implements Extension {
public string $defaultMethod = "get";
public array $token = [ "ui.form", "ui.endform", "ui.form.get", "ui.form.post", "ui.form.patch", "ui.form.delete", "ui.form.put" ];
public array $token = [ "ui:form", "ui:endform" /*, "ui:form.get", "ui:form.post", "ui:form.patch", "ui:form.delete", "ui:form.put"*/ ];
public string $tag = "form";
@@ -19,36 +19,41 @@ class UiForm extends UiElement implements Extension {
'class' => 'ui-form',
];
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string
{
switch($token) {
case 'ui.endform':
case 'ui:endform':
return "</form>";
}
case "ui.form.get":
$opt = $context->tokenOptions($token, true);
if (in_array('get', $opt)) {
$method = "get";
break;
case "ui.form.patch":
$method = "patch";
break;
case "ui.form.delete":
$method = "delete";
break;
case "ui.form.put":
$method = "put";
break;
case "ui.form.post":
}
elseif (in_array('post', $opt)) {
$method = "post";
break;
}
elseif (in_array('put', $opt)) {
$method = "put";
}
elseif (in_array('delete', $opt)) {
$method = "delete";
}
elseif (in_array('patch', $opt)) {
$method = "patch";
}
$method ??= $this->defaultMethod;
return "<?php echo ( new \\" . static::class . "() )->buildHtml('$method', $arguments) ?>";
return "<?php echo ( new \\" . static::class . "() )->parseOptions($opt)->buildHtml('$method', $arguments) ?>";
}
public function parseOptions($options) : self
{
$this->options = $options;
return $this;
}
public function buildHtml(string $method = "get", string $name = "", string $action = "", array $attributes = []) : string
@@ -57,7 +62,6 @@ class UiForm extends UiElement implements Extension {
$this->option('tag-type', 'single');
if ($attributes['class'] ?? false) {
$attributes['class'] .= " {$this->attributes['class']}";
unset($this->attributes['class']);
@@ -67,7 +71,7 @@ class UiForm extends UiElement implements Extension {
if ( $method !== "get" ) {
$token = md5( $name . microtime());
$key = "picea-ui.form:{$name}";
$key = "picea-ui:form:{$name}";
if (count($_SESSION[$key] ?? []) > 100) {
array_shift($_SESSION[$key]);
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiHidden extends UiInput {
public string $token = "ui.hidden";
public string $token = "ui:hidden";
public array $attributes = [
'class' => "ui-hidden",
+2 -2
View File
@@ -9,7 +9,7 @@ use Picea\Extension\ExtensionTrait;
class UiImage extends UiElement implements Extension {
use ExtensionTrait;
public string $token = "ui.img";
public array $tokens = [ "ui:img", "ui:image" ];
public string $tag = "img";
@@ -21,7 +21,7 @@ class UiImage extends UiElement implements Extension {
'tag-type' => "single",
];
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string
{
return "<?php echo ( new \\" . static::class . "() )->buildHtml($arguments) ?>";
}
+3 -3
View File
@@ -9,7 +9,7 @@ use Picea\Extension\ExtensionTrait;
class UiInput extends UiElement implements Extension {
use ExtensionTrait;
public string $token = "ui.input";
public string $token = "ui:input";
public string $tag = "input";
@@ -25,12 +25,12 @@ class UiInput extends UiElement implements Extension {
protected string $name;
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string
{
return "<?php echo ( new \\" . static::class . "() )->buildHtml($arguments) ?>";
}
public function buildHtml(string $name, /*? mixed */ $value = null, array $attributes = [], array $options = []) : string
public function buildHtml(string $name, mixed $value = null, array $attributes = [], array $options = []) : string
{
$this->name = $name;
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiNumeric extends UiInput {
public string $token = "ui.numeric";
public string $token = "ui:numeric";
public array $attributes = [
'class' => "ui-numeric",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiPassword extends UiInput {
public string $token = "ui.password";
public string $token = "ui:password";
public array $attributes = [
'class' => "ui-password",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiRadio extends UiInput {
public string $token = "ui.radio";
public string $token = "ui:radio";
public array $attributes = [
'class' => "ui-radio",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiRange extends UiInput {
public string $token = "ui.range";
public string $token = "ui:range";
public array $attributes = [
'class' => "ui-range",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiSearch extends UiInput {
public string $token = "ui.search";
public string $token = "ui:search";
public array $attributes = [
'class' => "ui-search",
+3 -3
View File
@@ -9,7 +9,7 @@ use Picea\Extension\ExtensionTrait;
class UiSelect extends UiElement implements Extension {
use ExtensionTrait;
public string $token = "ui.select";
public string $token = "ui:select";
public string $tag = "select";
@@ -17,12 +17,12 @@ class UiSelect extends UiElement implements Extension {
'class' => 'ui-select',
];
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string
{
return "<?php echo ( new \\" . static::class . "() )->buildHtml($arguments) ?>";
}
public function buildHtml(string $name, array $list, $value = null, array $attributes = [], bool $strictComparison = true) : string
public function buildHtml(string $name, array $list, mixed $value = null, array $attributes = [], bool $strictComparison = true) : string
{
if ($attributes['class'] ?? false) {
$attributes['class'] = implode(" ", array_merge((array) $attributes['class'], (array) $this->attributes['class']));
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiTel extends UiInput {
public string $token = "ui.tel";
public string $token = "ui:tel";
public array $attributes = [
'class' => "ui-tel",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiText extends UiInput {
public string $token = "ui.text";
public string $token = "ui:text";
public array $attributes = [
'class' => "ui-text",
+3 -8
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiTextarea extends UiInput {
public array $tokens = [ "ui.textarea", "ui.textarea.raw" ];
public array $tokens = [ "ui:textarea" ];
public string $tag = "textarea";
@@ -16,18 +16,13 @@ class UiTextarea extends UiInput {
protected bool $echoRaw = false;
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string
{
if ($token === 'ui.textarea.raw') {
$this->echoRaw = true;
}
$raw = $this->echoRaw ? 'true' : 'false';
$raw = in_array('raw', $context->tokenOptions($token, true)) ? 'true' : 'false';
return "<?php echo ( new \\" . static::class . "() )->echoRaw($raw)->buildHtml($arguments) ?>";
}
protected function setValue($value) : void
{
$this->echoRaw ? $this->html($value) : $this->text($value);
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiTime extends UiInput {
public string $token = "ui.time";
public string $token = "ui:time";
public array $attributes = [
'class' => "ui-time",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiUrl extends UiInput {
public string $token = "ui.url";
public string $token = "ui:url";
public array $attributes = [
'class' => "ui-url",
+1 -1
View File
@@ -4,7 +4,7 @@ namespace Picea\Ui\Form;
class UiWeek extends UiInput {
public string $token = "ui.week";
public string $token = "ui:week";
public array $attributes = [
'class' => "ui-week",
+7 -5
View File
@@ -7,9 +7,10 @@ use Picea\Extension\Extension,
use Picea\Compiler\Context;
use Picea\Extension\FunctionExtension;
use Psr\Http\Message\ServerRequestInterface;
class Form implements Extension {
class Form implements Extension, FunctionExtension {
use ExtensionTrait;
public array $tokens;
@@ -22,14 +23,15 @@ class Form implements Extension {
public function __construct(ServerRequestInterface $request, Context $context) {
$this->request = $request;
$this->register($context);
}
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string { }
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string { }
public function register(Context $context) : void
public function exportFunctions(): array
{
$context->pushFunction("form", [ $this, 'formClass' ]);
return [
"form" => [ $this, 'formClass' ],
];
}
public function formClass(FormInterface $form, ? FormContext $formContext = null) : FormHandler
+1 -1
View File
@@ -13,7 +13,7 @@ class FormContext implements FormContextInterface
public bool $formExecuted = false;
public /*mixed*/ $formExecutionStatus = null;
public mixed $formExecutionStatus = null;
public array $values = [];
+2 -2
View File
@@ -17,12 +17,12 @@ class FormHandler {
public ? bool $validationStatus = null;
public FormInterface $form;
public FormContext $context;
protected ServerRequestInterface $request;
protected FormInterface $form;
public array $acceptedMethods = self::DEFAULT_METHODS;
public function __construct(ServerRequestInterface $request, FormInterface $form, ? FormContextInterface $context = null)
+1 -1
View File
@@ -8,5 +8,5 @@ interface FormInterface
public function validate(FormContextInterface $context) : bool;
public function execute(FormContextInterface $context) /* : mixed */;
public function execute(FormContextInterface $context);
}
+8 -5
View File
@@ -7,9 +7,10 @@ use Picea\Extension\Extension,
use Picea\Compiler\Context;
use Picea\Extension\FunctionExtension;
use Psr\Http\Message\ServerRequestInterface;
class Pagination implements Extension {
class Pagination implements Extension, FunctionExtension {
use ExtensionTrait;
public array $tokens;
@@ -20,14 +21,16 @@ class Pagination implements Extension {
public function __construct(ServerRequestInterface $request, Context $context) {
$this->request = $request;
$this->register($context);
}
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) : string { }
public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token) : string { }
public function register(Context $context) : void
public function exportFunctions(): array
{
$context->pushFunction("pagination", [ $this, 'paginationClass' ]);
return [
"pagination" => [ $this, 'paginationClass' ]
];
}
public function paginationClass(string $name, ?string $url = null, ?array $params = null) : PaginationHandler
+1 -1
View File
@@ -41,7 +41,7 @@ class PaginationHandler {
}
public function __toString() {
return "hello world";
return "";
}
}
+3
View File
@@ -8,6 +8,9 @@ class Ui {
public function registerFormExtension(Compiler $compiler) : self
{
# BW compatibility with v1.x syntax
$compiler->registerExtension(new Form\Ui());
$compiler->registerExtension(new Form\UiForm());
$compiler->registerExtension(new Form\UiInput());
$compiler->registerExtension(new Form\UiCheckbox());