Skip to content

Commit

Permalink
forms component
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisGalliano committed May 21, 2019
1 parent 6abbe7c commit 81e600e
Show file tree
Hide file tree
Showing 48 changed files with 1,505 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/Forms/BaseForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?
declare(strict_types=1);

namespace Pion\Forms;

use Pion\Forms\Elements\FormElementInterface;
use Pion\Forms\Elements\Validation\Collection\ElementValidationResultsCollection;
use Pion\Forms\Handle\HandlingResult;
use Pion\Forms\Handle\HandlingResultInterface;
use Pion\Http\Request\Parameters\ParametersInterface;

abstract class BaseForm implements FormInterface
{
/**
* @var FormElementInterface[]
*/
private $elements;

public function __construct(FormElementInterface...$elements)
{
$this->elements = $elements;
}

public function handle(ParametersInterface $parameters): HandlingResultInterface
{
$isSubmitted = $parameters->has($this->name());
$validationResult = new ElementValidationResultsCollection();
if ($isSubmitted) {
foreach ($this->elements as $element) {
$validationResult = $validationResult->merge($element->handle($parameters));
}
}

return new HandlingResult($isSubmitted, $validationResult);
}
}
17 changes: 17 additions & 0 deletions src/Forms/Elements/FormElementInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?
declare(strict_types=1);

namespace Pion\Forms\Elements;

use Pion\Forms\Elements\Validation\Collection\ElementValidationResultsCollectionInterface;
use Pion\Http\Request\Parameters\ParametersInterface;
use Pion\Templating\Engine\EngineInterface;

interface FormElementInterface
{
public function name(): string;

public function handle(ParametersInterface $parameters): ElementValidationResultsCollectionInterface;

public function render(EngineInterface $engine): string;
}
79 changes: 79 additions & 0 deletions src/Forms/Elements/Input/Checkbox/CheckboxElement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?
declare(strict_types=1);

namespace Pion\Forms\Elements\Input\Checkbox;

use Pion\Forms\Elements\FormElementInterface;
use Pion\Forms\Elements\Multiple\Options\OptionInterface;
use Pion\Forms\Elements\Validation\Collection\ElementValidationResultsCollection;
use Pion\Forms\Elements\Validation\Collection\ElementValidationResultsCollectionInterface;
use Pion\Forms\Elements\Validation\Display\ErrorsWidget;
use Pion\Forms\Elements\Validation\ElementValidationResult;
use Pion\Http\Request\Parameters\ParametersInterface;
use Pion\Spl\Types\Boolean\BooleanInterface;
use Pion\Spl\Types\Boolean\Validation\BooleanValidatorInterface;
use Pion\Templating\Engine\EngineInterface;
use Pion\Validation\Result\ValidationResult;
use Pion\Validation\Result\ValidationResultInterface;

class CheckboxElement implements FormElementInterface, BooleanInterface
{
/**
* @var OptionInterface
*/
private $option;

/**
* @var bool
*/
private $value = false;

/**
* @var BooleanValidatorInterface
*/
private $validator;

/**
* @var ValidationResultInterface
*/
private $validationResult;

public function __construct(OptionInterface $option, BooleanValidatorInterface $validator)
{
$this->option = $option;
$this->validator = $validator;
$this->validationResult = new ValidationResult();
}

public function name(): string
{
return $this->option->value();
}

public function handle(ParametersInterface $parameters): ElementValidationResultsCollectionInterface
{
$this->value = $parameters->has($this->name());
$this->validationResult = $this->validator->validate($this);
return new ElementValidationResultsCollection(
new ElementValidationResult($this, $this->validationResult)
);
}

public function render(EngineInterface $engine): string
{
return $engine->render(
__DIR__ . '/CheckboxElementView.html',
[
'errors' => (new ErrorsWidget($this->validationResult))->render($engine),
'name' => $this->name(),
'checked' => $this->bool(),
'label' => $this->option->label(),
]
);
}

public function bool(): bool
{
return $this->value;
}
}
17 changes: 17 additions & 0 deletions src/Forms/Elements/Input/Checkbox/CheckboxElementView.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?
declare(strict_types=1);

assert(is_string($errors));
assert(is_string($name));
assert(is_bool($checked));
assert(is_string($label));
$elementId = 'checkbox-el-' . $name;
?>
<div class="checkbox-element form-element">
<?= $errors ?>
<div class="element-content">
<input type="checkbox" name="<?= $name ?>" <?= $checked ? 'checked="checked"' : '' ?>
id="<?= $elementId ?>">
<label for="#<?= $elementId ?>"><?= $label ?></label>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?
declare(strict_types=1);

namespace Pion\Forms\Elements\Input\Checkbox\Multiple;

use Pion\Forms\Elements\FormElementInterface;
use Pion\Forms\Elements\Input\Checkbox\CheckboxElement;
use Pion\Forms\Elements\Multiple\Options\ListOfOptionsInterface;
use Pion\Forms\Elements\Validation\Collection\ElementValidationResultsCollection;
use Pion\Forms\Elements\Validation\Collection\ElementValidationResultsCollectionInterface;
use Pion\Forms\Elements\Validation\Display\ErrorsWidget;
use Pion\Forms\Elements\Validation\ElementValidationResult;
use Pion\Http\Request\Parameters\ParametersInterface;
use Pion\Spl\Types\Boolean\BooleanInterface;
use Pion\Spl\Types\Boolean\Multiple\ListOfBooleansInterface;
use Pion\Spl\Types\Boolean\Multiple\Validation\ListOfBooleansValidatorInterface;
use Pion\Spl\Types\Boolean\Validation\DummyBooleanValidator;
use Pion\Templating\Engine\EngineInterface;
use Pion\Validation\Result\ValidationResult;
use Pion\Validation\Result\ValidationResultInterface;

class ListOfCheckboxesElement implements FormElementInterface, ListOfBooleansInterface
{
/**
* @var string
*/
private $name;

/**
* @var CheckboxElement[]
*/
private $checkboxes = [];

/**
* @var ListOfBooleansValidatorInterface
*/
private $validator;

/**
* @var ValidationResultInterface
*/
private $validationResult;

public function __construct(
string $name, ListOfOptionsInterface $options, ListOfBooleansValidatorInterface $validator
) {
$this->name = $name;
foreach ($options->all() as $option) {
$this->checkboxes[] = new CheckboxElement($option, new DummyBooleanValidator());
}
$this->validator = $validator;
$this->validationResult = new ValidationResult();
}

public function name(): string
{
return $this->name;
}

public function handle(ParametersInterface $parameters): ElementValidationResultsCollectionInterface
{
foreach ($this->checkboxes() as $checkbox) {
$checkbox->handle($parameters);
}
$this->validationResult = $this->validator->validate($this);
return new ElementValidationResultsCollection(
new ElementValidationResult($this, $this->validationResult)
);
}

/**
* @return CheckboxElement[]
*/
public function checkboxes(): array
{
return $this->checkboxes;
}

public function render(EngineInterface $engine): string
{
return $engine->render(
__DIR__ . '/ListOfCheckboxesView.html',
[
'errors' => (new ErrorsWidget($this->validationResult))->render($engine),
'engine' => $engine,
'checkboxes' => $this->checkboxes(),
]
);
}

/**
* @return BooleanInterface[]|\Generator
*/
public function booleans(): \Generator
{
yield from $this->checkboxes();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?
declare(strict_types=1);

use Pion\Forms\Elements\Input\Checkbox\CheckboxElement;
use Pion\Templating\Engine\EngineInterface;

assert(is_string($errors));
assert(is_array($checkboxes));
assert($engine instanceof EngineInterface);
?>
<div class="list-of-checkboxes-element form-element">
<?= $errors ?>
<div class="element-content">
<? foreach ($checkboxes as $checkbox) { ?>
<? assert($checkbox instanceof CheckboxElement) ?>
<?= $checkbox->render($engine) ?>
<? } ?>
</div>
</div>
81 changes: 81 additions & 0 deletions src/Forms/Elements/Input/Hidden/HiddenInputElement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?
declare(strict_types=1);

namespace Pion\Forms\Elements\Input\Hidden;

use Pion\Forms\Elements\FormElementInterface;
use Pion\Forms\Elements\Validation\Collection\ElementValidationResultsCollection;
use Pion\Forms\Elements\Validation\Collection\ElementValidationResultsCollectionInterface;
use Pion\Forms\Elements\Validation\ElementValidationResult;
use Pion\Http\Request\Parameters\ParametersInterface;
use Pion\Spl\Types\String\StringInterface;
use Pion\Spl\Types\String\Validation\StringValidatorInterface;
use Pion\Templating\Engine\EngineInterface;
use Pion\Validation\Result\ValidationResult;
use Pion\Validation\Result\ValidationResultInterface;

class HiddenInputElement implements FormElementInterface, StringInterface
{
/**
* @var string
*/
private $name;

/**
* @var string
*/
private $value = '';

/**
* @var StringValidatorInterface
*/
private $validator;

/**
* @var ValidationResultInterface
*/
private $validationResult;

public function __construct(string $name, StringValidatorInterface $validator)
{
$this->name = $name;
$this->validator = $validator;
$this->validationResult = new ValidationResult();
}

public function string(): string
{
return $this->value;
}

public function name(): string
{
return $this->name;
}

public function handle(ParametersInterface $parameters): ElementValidationResultsCollectionInterface
{
$this->setValue($parameters->has($this->name()) ? $parameters->require($this->name()) : '');
$this->validationResult = $this->validator->validate($this);
return new ElementValidationResultsCollection(
new ElementValidationResult($this, $this->validationResult)
);
}

public function render(EngineInterface $engine): string
{
return $engine->render(
__DIR__ . '/HiddenInputElementView.html',
[
'name' => $this->name(),
'value' => $this->string(),
]
);
}

public function setValue(string $value): self
{
$this->value = $value;
return $this;
}
}
11 changes: 11 additions & 0 deletions src/Forms/Elements/Input/Hidden/HiddenInputElementView.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?
declare(strict_types=1);

assert(is_string($name));
assert(is_string($value));
?>
<div class="hidden-element form-element">
<div class="element-content">
<input type="hidden" name="<?= $name ?>" value="<?= $value ?>">
</div>
</div>
Loading

0 comments on commit 81e600e

Please sign in to comment.