Skip to content

Commit

Permalink
add errors
Browse files Browse the repository at this point in the history
  • Loading branch information
TomK committed Feb 1, 2019
1 parent 1a0c46e commit a8712fd
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 22 deletions.
6 changes: 2 additions & 4 deletions src/Csrf/CsrfDataHandler.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<?php
namespace PackagedUi\Form\Csrf;

use Packaged\Glimpse\Tags\Form\Input;
use PackagedUi\Form\DataHandlers\AbstractDataHandler;
use PackagedUi\Form\Decorators\InputDecorator;
use PackagedUi\Form\Decorators\HiddenInputDecorator;
use PackagedUi\Form\Decorators\Interfaces\DataHandlerDecorator;

class CsrfDataHandler extends AbstractDataHandler
Expand Down Expand Up @@ -85,9 +84,8 @@ protected function _setupValidator()

protected function _defaultDecorator(): DataHandlerDecorator
{
$decorator = new InputDecorator();
$decorator = new HiddenInputDecorator();
$decorator->setHandler($this);
$decorator->setType(Input::TYPE_HIDDEN);
return $decorator;
}
}
19 changes: 19 additions & 0 deletions src/DataHandlers/AbstractDataHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ abstract class AbstractDataHandler implements DataHandler

/** @var DataHandlerDecorator */
protected $_decorator;
protected $_errors = [];

public function getErrors(): array
{
return $this->_errors;
}

public function addError(ValidationException ...$errors)
{
$this->_errors = array_merge($this->_errors, $errors);
return $this;
}

public function clearErrors()
{
$this->_errors = [];
return $this;
}

/**
* @var IValidator[]
Expand Down Expand Up @@ -101,6 +119,7 @@ private function _initValidator()
{
if(!$this->_isValidatorSetUp)
{
$this->_isValidatorSetUp = true;
$this->_setupValidator();
}
}
Expand Down
35 changes: 35 additions & 0 deletions src/DataHandlers/Interfaces/DataHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
namespace PackagedUi\Form\DataHandlers\Interfaces;

use Packaged\Validate\IValidatable;
use Packaged\Validate\ValidationException;
use PackagedUi\Form\Decorators\Interfaces\DataHandlerDecorator;

interface DataHandler extends IValidatable
Expand Down Expand Up @@ -44,21 +45,55 @@ public function formatValue($value);

public function getName(): ?string;

/**
* @param string $name
*
* @return DataHandler
*/
public function setName($name);

public function getValue();

/**
* @param mixed $value
*
* @return DataHandler
*/
public function setValue($value);

public function getDecorator(): DataHandlerDecorator;

public function getDefaultValue();

/**
* @param string $placeholder
*
* @return DataHandler
*/
public function setPlaceholder($placeholder);

public function getPlaceholder();

/**
* @param string $label
*
* @return DataHandler
*/
public function setLabel($label);

public function getLabel();

public function getErrors(): array;

/**
* @param ValidationException ...$errors
*
* @return DataHandler
*/
public function addError(ValidationException ...$errors);

/**
* @return DataHandler
*/
public function clearErrors();
}
55 changes: 47 additions & 8 deletions src/Decorators/AbstractDataHandlerDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
use Packaged\Glimpse\Core\HtmlTag;
use Packaged\Glimpse\Tags\Div;
use Packaged\Glimpse\Tags\Form\Label;
use Packaged\Glimpse\Tags\Lists\ListItem;
use Packaged\Glimpse\Tags\Lists\UnorderedList;
use Packaged\Helpers\Objects;
use Packaged\Helpers\Strings;
use PackagedUi\Form\DataHandlers\Interfaces\DataHandler;
use PackagedUi\Form\Decorators\Interfaces\DataHandlerDecorator;
Expand All @@ -14,16 +17,20 @@ abstract class AbstractDataHandlerDecorator extends AbstractDecorator implements
* @var DataHandler
*/
protected $_handler;
/**
* @var callable
*/
protected $_formatCallback;

public function setHandler(DataHandler $handler)
{
$this->_handler = $handler;
return $this;
}

abstract protected function _getInput(): HtmlTag;
abstract protected function _getInputElement(): HtmlTag;

protected function _getLabel(): ?HtmlTag
protected function _getLabelElement(): ?HtmlTag
{
$labelText = $this->_handler->getLabel()
?? Strings::titleize(Strings::splitOnCamelCase($this->_handler->getName()));
Expand All @@ -38,8 +45,8 @@ protected function _getLabel(): ?HtmlTag

protected function _getElement()
{
$input = $this->_getInput();
$label = $this->_getLabel();
$input = $this->_getInputElement();
$label = $this->_getLabelElement();
if($label)
{
$id = $input->getId();
Expand All @@ -56,16 +63,48 @@ protected function _getElement()
}
$label->setAttribute('for', $id);
}
return $this->_formatElements($input, $label);

$errorTag = $this->_getErrorElement();
return $this->_formatElements($input, $label, $errorTag);
}

protected function _getErrorElement()
{
$errorTag = null;
$errors = $this->_handler->getErrors();
if($errors)
{
$errorTag = UnorderedList::create()
->setContent(ListItem::collection(Objects::mpull($errors, 'getMessage')))
->addClass('validation-errors');
}
return $errorTag;
}

protected function _formatElements(HtmlTag $input, ?HtmlTag $label)
protected function _formatElements(HtmlTag $input, ?HtmlTag $label, ?HtmlTag $errors)
{
$callback = $this->_formatCallback;
if(is_callable($callback))
{
return $callback($input, $label, $errors);
}

$return = Div::create()->addClass('form-group');
if($label)
{
return Div::create([$label, $input])->addClass('form-group');
$return->appendContent($label);
}
if($errors)
{
$return->appendContent($errors);
}
return $input;
$return->appendContent($input);
return $return;
}

public function setFormatCallback(callable $callback)
{
$this->_formatCallback = $callback;
return $this;
}
}
15 changes: 15 additions & 0 deletions src/Decorators/HiddenInputDecorator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
namespace PackagedUi\Form\Decorators;

use Packaged\Glimpse\Tags\Form\Input;
use Packaged\SafeHtml\SafeHtml;

class HiddenInputDecorator extends InputDecorator
{
protected $_type = Input::TYPE_HIDDEN;

public function produceSafeHTML(): SafeHtml
{
return SafeHtml::escape([$this->_getInputElement(), $this->_handler->getErrors()], '');
}
}
6 changes: 3 additions & 3 deletions src/Decorators/InputDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function setType($type)
return $this;
}

protected function _getInput(): HtmlTag
protected function _getInputElement(): HtmlTag
{
$input = Input::create();
$input->setId($this->getId());
Expand All @@ -48,13 +48,13 @@ protected function _getInput(): HtmlTag
return $input;
}

protected function _getLabel(): ?HtmlTag
protected function _getLabelElement(): ?HtmlTag
{
if($this->getType() === Input::TYPE_HIDDEN)
{
return null;
}
return parent::_getLabel();
return parent::_getLabelElement();
}

}
2 changes: 2 additions & 0 deletions src/Decorators/Interfaces/DataHandlerDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ interface DataHandlerDecorator extends Decorator
* @return $this
*/
public function setHandler(DataHandler $handler);

public function setFormatCallback(callable $callable);
}
2 changes: 1 addition & 1 deletion src/Decorators/SelectDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class SelectDecorator extends AbstractDataHandlerDecorator
{
protected function _getInput(): HtmlTag
protected function _getInputElement(): HtmlTag
{
$element = Select::create()
->setId($this->getId());
Expand Down
1 change: 1 addition & 0 deletions src/Form/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ public function validate(): array
$handlerErrors = $handler->validate();
if($handlerErrors)
{
$handler->clearErrors()->addError(...$handlerErrors);
if(!isset($errors[$name]))
{
$errors[$name] = [];
Expand Down
2 changes: 1 addition & 1 deletion tests/DataHandlers/AbstractDataHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public function testAccessor()
public function testRender()
{
$fdh = new TestAbstractDataHandler();
$this->assertEquals('<input type="text" />', $fdh->getDecorator()->render());
$this->assertEquals('<div class="form-group"><input type="text" /></div>', $fdh->getDecorator()->render());

$fdh->setName('myName');
$this->assertRegExp(
Expand Down
10 changes: 5 additions & 5 deletions tests/DataHandlers/EnumDataHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ class EnumDataHandlerTest extends TestCase
public function testGetElement()
{
$ele = new EnumDataHandler();
$this->assertEquals('<select></select>', $ele->getDecorator()->render());
$this->assertEquals('<div class="form-group"><select></select></div>', $ele->getDecorator()->render());

$ele->setOptions(['a' => 'one', 'b' => 'two']);
$this->assertEquals(
'<select><option value="a">one</option><option value="b">two</option></select>',
'<div class="form-group"><select><option value="a">one</option><option value="b">two</option></select></div>',
$ele->getDecorator()->render()
);

$ele->setValue('b');
$this->assertEquals(
'<select><option value="a">one</option><option value="b" selected="selected">two</option></select>',
'<div class="form-group"><select><option value="a">one</option><option value="b" selected="selected">two</option></select></div>',
$ele->getDecorator()->render()
);

Expand All @@ -29,15 +29,15 @@ public function testGetElement()
$this->assertTrue($ele->isValidValue('c'));

$this->assertEquals(
'<select><option value="a">one</option><option value="b" selected="selected">two</option><option value="c">three</option></select>',
'<div class="form-group"><select><option value="a">one</option><option value="b" selected="selected">two</option><option value="c">three</option></select></div>',
$ele->getDecorator()->render()
);

$this->assertFalse($ele->isValidValue('d'));

$ele->getDecorator()->setId('mySelect');
$this->assertEquals(
'<select id="mySelect"><option value="a">one</option><option value="b" selected="selected">two</option><option value="c">three</option></select>',
'<div class="form-group"><select id="mySelect"><option value="a">one</option><option value="b" selected="selected">two</option><option value="c">three</option></select></div>',
$ele->getDecorator()->render()
);
}
Expand Down
16 changes: 16 additions & 0 deletions tests/DataHandlers/TextDataHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace PackagedUi\Tests\Form\DataHandlers;

use Packaged\Glimpse\Tags\Form\Input;
use PackagedUi\Form\DataHandlers\TextDataHandler;
use PackagedUi\Form\Decorators\InputDecorator;
use PHPUnit\Framework\TestCase;
use stdClass;

Expand All @@ -24,4 +26,18 @@ public function testFormatValue()
$text->setValueFormatted(false);
$this->assertEquals('false', $text->getValue());
}

public function testHidden()
{
$dec = new InputDecorator();
$dec->setType(Input::TYPE_HIDDEN);

$text = new TextDataHandler();
$text->setName('text');
$text->setDecorator($dec);
$this->assertEquals(
'<div class="form-group"><input type="hidden" name="text" /></div>',
$text->getDecorator()->render()
);
}
}
15 changes: 15 additions & 0 deletions tests/FormTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,20 @@ public function testRender()
$form->render()
);
$this->assertfalse($form->getDecorator()->hasAttribute('data-test'));

// assert should not throw
$form->assert();

$form->number = 'abc';
$decorator = $form->number->getDecorator();
$decorator->setId('myNum');
$form->validate();
$this->assertEquals(
'<form id="abc" method="POST" action="/test"><div class="form-group"><label for="myInput">Text</label><input type="text" id="myInput" name="text" value="abc" /></div><div class="form-group"><label for="myNum">Number</label><ul class="validation-errors"><li>must be a number</li></ul><input type="number" id="myNum" name="number" value="abc" /></div></form>',
$form->render()
);

$decorator->setFormatCallback(function ($input, $label, $err) { return $input; });
$this->assertEquals('<input type="number" id="myNum" name="number" value="abc" />', $decorator->render());
}
}

0 comments on commit a8712fd

Please sign in to comment.