Skip to content

Commit

Permalink
added Container::setMappedType() and parameter getValues($returnType)…
Browse files Browse the repository at this point in the history
… for mapping to objects
  • Loading branch information
dg committed Feb 8, 2019
1 parent 032cf95 commit dcd80e5
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 15 deletions.
38 changes: 29 additions & 9 deletions src/Forms/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
namespace Nette\Forms;

use Nette;
use Nette\Utils\ArrayHash;


/**
* Container for form controls.
*
* @property Nette\Utils\ArrayHash $values
* @property ArrayHash $values
* @property-read \Iterator $controls
* @property-read Form|null $form
*/
Expand All @@ -35,6 +36,9 @@ class Container extends Nette\ComponentModel\Container implements \ArrayAccess
/** @var bool */
private $validated;

/** @var string */
private $mappedType = ArrayHash::class;


/********************* data exchange ****************d*g**/

Expand Down Expand Up @@ -96,20 +100,36 @@ public function setValues($data, bool $erase = false)

/**
* Returns the values submitted by the form.
* @return Nette\Utils\ArrayHash|array
* @param string|null $returnType 'array' for array
* @return object|array
*/
public function getValues(bool $asArray = false)
public function getValues($returnType = null)
{
$values = $asArray ? [] : new Nette\Utils\ArrayHash;
$returnType = $returnType
? ($returnType === true ? 'array' : $returnType) // back compatibility
: $this->mappedType;

$isArray = $returnType === 'array';
$obj = $isArray ? new \stdClass : new $returnType;

foreach ($this->getComponents() as $name => $control) {
if ($control instanceof IControl && !$control->isOmitted()) {
$values[$name] = $control->getValue();

$obj->$name = $control->getValue();
} elseif ($control instanceof self) {
$values[$name] = $control->getValues($asArray);
$obj->$name = $control->getValues($isArray ? 'array' : null);
}
}
return $values;
return $isArray ? (array) $obj : $obj;
}


/**
* @return static
*/
public function setMappedType(string $type)
{
$this->mappedType = $type;
return $this;
}


Expand Down Expand Up @@ -148,7 +168,7 @@ public function validate(array $controls = null): void
}
foreach ($this->onValidate as $handler) {
$params = Nette\Utils\Callback::toReflection($handler)->getParameters();
$values = isset($params[1]) ? $this->getValues($params[1]->isArray()) : null;
$values = isset($params[1]) ? $this->getValues((string) $params[1]->getType()) : null;
$handler($this, $values);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ private function invokeHandlers(iterable $handlers, $button = null): void
{
foreach ($handlers as $handler) {
$params = Nette\Utils\Callback::toReflection($handler)->getParameters();
$values = isset($params[1]) ? $this->getValues($params[1]->isArray()) : null;
$values = isset($params[1]) ? $this->getValues((string) $params[1]->getType()) : null;
$handler($button ?: $this, $values);
if (!$this->isValid()) {
return;
Expand Down
55 changes: 55 additions & 0 deletions tests/Forms/Container.values.array.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,61 @@ test(function () { // setValues() + array
});


test(function () { // getValues(...arguments...)
$_SERVER['REQUEST_METHOD'] = 'POST';

$form = createForm();

Assert::truthy($form->isSubmitted());

$form->setValues([
'title' => 'new1',
'first' => [
'name' => 'new2',
],
]);

Assert::equal([
'title' => 'new1',
'first' => [
'name' => 'new2',
'age' => '999',
'second' => [
'city' => 'sent city',
],
],
], $form->getValues('array'));
});


test(function () { // setMappedType(array)
$_SERVER['REQUEST_METHOD'] = 'POST';

$form = createForm();
$form->setMappedType('array');

Assert::truthy($form->isSubmitted());

$form->setValues([
'title' => 'new1',
'first' => [
'name' => 'new2',
],
]);

Assert::equal([
'title' => 'new1',
'first' => [
'name' => 'new2',
'age' => '999',
'second' => [
'city' => 'sent city',
],
],
], $form->getValues());
});


test(function () { // onSuccess test
$_SERVER['REQUEST_METHOD'] = 'POST';

Expand Down
83 changes: 78 additions & 5 deletions tests/Forms/Container.values.mapping.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ test(function () { // submitted form + getValues()
$_SERVER['REQUEST_METHOD'] = 'POST';

$form = createForm();
$form->setMappedType(FormData::class);

Assert::truthy($form->isSubmitted());
Assert::equal(ArrayHash::from([
Assert::equal(hydrate(FormData::class, [
'title' => 'sent title',
'first' => ArrayHash::from([
'name' => '',
Expand All @@ -127,12 +129,14 @@ test(function () { // submitted form + reset()
$_SERVER['REQUEST_METHOD'] = 'POST';

$form = createForm();
$form->setMappedType(FormData::class);

Assert::truthy($form->isSubmitted());

$form->reset();

Assert::false($form->isSubmitted());
Assert::equal(ArrayHash::from([
Assert::equal(hydrate(FormData::class, [
'title' => '',
'first' => ArrayHash::from([
'name' => '',
Expand All @@ -149,6 +153,8 @@ test(function () { // setValues() + object
$_SERVER['REQUEST_METHOD'] = 'POST';

$form = createForm();
$form->setMappedType(FormData::class);

Assert::truthy($form->isSubmitted());

$form->setValues(hydrate(FormData::class, [
Expand All @@ -159,7 +165,7 @@ test(function () { // setValues() + object
]),
]));

Assert::equal(ArrayHash::from([
Assert::equal(hydrate(FormData::class, [
'title' => 'new1',
'first' => ArrayHash::from([
'name' => 'new2',
Expand All @@ -178,7 +184,7 @@ test(function () { // setValues() + object
]),
]), true);

Assert::equal(ArrayHash::from([
Assert::equal(hydrate(FormData::class, [
'title' => 'new1',
'first' => ArrayHash::from([
'name' => 'new2',
Expand All @@ -191,10 +197,64 @@ test(function () { // setValues() + object
});


test(function () { // getValues(...arguments...)
$_SERVER['REQUEST_METHOD'] = null;

$form = createForm();

$form->setValues([
'title' => 'new1',
'first' => [
'name' => 'new2',
],
]);

Assert::equal(hydrate(FormData::class, [
'title' => 'new1',
'first' => ArrayHash::from([
'name' => 'new2',
'age' => null,
'second' => ArrayHash::from([
'city' => '',
]),
]),
]), $form->getValues(FormData::class));


$form->setMappedType(FormData::class);
$form['first']->setMappedType(FormFirstLevel::class);
$form['first-second']->setMappedType(FormSecondLevel::class);

Assert::equal(hydrate(FormData::class, [
'title' => 'new1',
'first' => hydrate(FormFirstLevel::class, [
'name' => 'new2',
'age' => null,
'second' => hydrate(FormSecondLevel::class, [
'city' => '',
]),
]),
]), $form->getValues());

Assert::equal([
'title' => 'new1',
'first' => [
'name' => 'new2',
'age' => null,
'second' => [
'city' => '',
],
],
], $form->getValues(true));
});


test(function () { // onSuccess test
$_SERVER['REQUEST_METHOD'] = 'POST';

$form = createForm();
$form->setMappedType(FormData::class);

$form->onSuccess[] = function (Form $form, array $values) {
Assert::same([
'title' => 'sent title',
Expand Down Expand Up @@ -222,7 +282,20 @@ test(function () { // onSuccess test
};

$form->onSuccess[] = function (Form $form, $values) {
Assert::equal(ArrayHash::from([
Assert::equal(hydrate(FormData::class, [
'title' => 'sent title',
'first' => ArrayHash::from([
'name' => '',
'age' => 999,
'second' => ArrayHash::from([
'city' => 'sent city',
]),
]),
]), $values);
};

$form->onSuccess[] = function (Form $form, FormData $values) {
Assert::equal(hydrate(FormData::class, [
'title' => 'sent title',
'first' => ArrayHash::from([
'name' => '',
Expand Down

0 comments on commit dcd80e5

Please sign in to comment.