Skip to content

Commit 032cf95

Browse files
committed
Container::setValues() & setDefaults() accepts plain objects
1 parent 73720c7 commit 032cf95

File tree

2 files changed

+256
-7
lines changed

2 files changed

+256
-7
lines changed

src/Forms/Container.php

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,30 +41,35 @@ class Container extends Nette\ComponentModel\Container implements \ArrayAccess
4141

4242
/**
4343
* Fill-in with default values.
44+
* @param array|object $data
4445
* @return static
4546
*/
46-
public function setDefaults(iterable $values, bool $erase = false)
47+
public function setDefaults($data, bool $erase = false)
4748
{
4849
$form = $this->getForm(false);
4950
if (!$form || !$form->isAnchored() || !$form->isSubmitted()) {
50-
$this->setValues($values, $erase);
51+
$this->setValues($data, $erase);
5152
}
5253
return $this;
5354
}
5455

5556

5657
/**
5758
* Fill-in with values.
59+
* @param array|object $data
5860
* @return static
5961
* @internal
6062
*/
61-
public function setValues(iterable $values, bool $erase = false)
63+
public function setValues($data, bool $erase = false)
6264
{
63-
if ($values instanceof \Traversable) {
64-
$values = iterator_to_array($values);
65+
if ($data instanceof \Traversable) {
66+
$values = iterator_to_array($data);
6567

66-
} elseif (!is_array($values)) {
67-
throw new Nette\InvalidArgumentException(sprintf('First parameter must be an array, %s given.', gettype($values)));
68+
} elseif (is_object($data) || is_array($data) || $data === null) {
69+
$values = (array) $data;
70+
71+
} else {
72+
throw new Nette\InvalidArgumentException(sprintf('First parameter must be an array or object, %s given.', gettype($data)));
6873
}
6974

7075
foreach ($this->getComponents() as $name => $control) {
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Nette\Forms\Form;
6+
use Nette\Utils\ArrayHash;
7+
use Tester\Assert;
8+
9+
10+
require __DIR__ . '/../bootstrap.php';
11+
12+
13+
class FormData
14+
{
15+
/** @var string */
16+
public $title;
17+
18+
/** @var FormFirstLevel */
19+
public $first;
20+
}
21+
22+
23+
class FormFirstLevel
24+
{
25+
/** @var string */
26+
public $name;
27+
28+
/** @var int */
29+
public $age;
30+
31+
/** @var FormSecondLevel */
32+
public $second;
33+
}
34+
35+
36+
class FormSecondLevel
37+
{
38+
/** @var string */
39+
public $city;
40+
}
41+
42+
43+
function hydrate(string $class, array $data)
44+
{
45+
$obj = new $class;
46+
foreach ($data as $key => $value) {
47+
$obj->$key = $value;
48+
}
49+
return $obj;
50+
}
51+
52+
53+
$_POST = [
54+
'title' => 'sent title',
55+
'first' => [
56+
'age' => '999',
57+
'second' => [
58+
'city' => 'sent city',
59+
],
60+
],
61+
];
62+
63+
64+
function createForm(): Form
65+
{
66+
$form = new Form;
67+
$form->addText('title');
68+
69+
$first = $form->addContainer('first');
70+
$first->addText('name');
71+
$first->addInteger('age');
72+
73+
$second = $first->addContainer('second');
74+
$second->addText('city');
75+
return $form;
76+
}
77+
78+
79+
test(function () { // setDefaults() + object
80+
$form = createForm();
81+
Assert::false($form->isSubmitted());
82+
83+
$form->setDefaults(hydrate(FormData::class, [
84+
'title' => 'xxx',
85+
'extra' => '50',
86+
'first' => hydrate(FormFirstLevel::class, [
87+
'name' => 'yyy',
88+
'age' => '30',
89+
'second' => hydrate(FormSecondLevel::class, [
90+
'city' => 'zzz',
91+
]),
92+
]),
93+
]));
94+
95+
Assert::same([
96+
'title' => 'xxx',
97+
'first' => [
98+
'name' => 'yyy',
99+
'age' => '30',
100+
'second' => [
101+
'city' => 'zzz',
102+
],
103+
],
104+
], $form->getValues(true));
105+
});
106+
107+
108+
test(function () { // submitted form + getValues()
109+
$_SERVER['REQUEST_METHOD'] = 'POST';
110+
111+
$form = createForm();
112+
Assert::truthy($form->isSubmitted());
113+
Assert::equal(ArrayHash::from([
114+
'title' => 'sent title',
115+
'first' => ArrayHash::from([
116+
'name' => '',
117+
'age' => '999',
118+
'second' => ArrayHash::from([
119+
'city' => 'sent city',
120+
]),
121+
]),
122+
]), $form->getValues());
123+
});
124+
125+
126+
test(function () { // submitted form + reset()
127+
$_SERVER['REQUEST_METHOD'] = 'POST';
128+
129+
$form = createForm();
130+
Assert::truthy($form->isSubmitted());
131+
132+
$form->reset();
133+
134+
Assert::false($form->isSubmitted());
135+
Assert::equal(ArrayHash::from([
136+
'title' => '',
137+
'first' => ArrayHash::from([
138+
'name' => '',
139+
'age' => null,
140+
'second' => ArrayHash::from([
141+
'city' => '',
142+
]),
143+
]),
144+
]), $form->getValues());
145+
});
146+
147+
148+
test(function () { // setValues() + object
149+
$_SERVER['REQUEST_METHOD'] = 'POST';
150+
151+
$form = createForm();
152+
Assert::truthy($form->isSubmitted());
153+
154+
$form->setValues(hydrate(FormData::class, [
155+
'title' => 'new1',
156+
'first' => hydrate(FormFirstLevel::class, [
157+
'name' => 'new2',
158+
// age => null
159+
]),
160+
]));
161+
162+
Assert::equal(ArrayHash::from([
163+
'title' => 'new1',
164+
'first' => ArrayHash::from([
165+
'name' => 'new2',
166+
'age' => null,
167+
'second' => ArrayHash::from([
168+
'city' => 'sent city',
169+
]),
170+
]),
171+
]), $form->getValues());
172+
173+
// erase
174+
$form->setValues(hydrate(FormData::class, [
175+
'title' => 'new1',
176+
'first' => hydrate(FormFirstLevel::class, [
177+
'name' => 'new2',
178+
]),
179+
]), true);
180+
181+
Assert::equal(ArrayHash::from([
182+
'title' => 'new1',
183+
'first' => ArrayHash::from([
184+
'name' => 'new2',
185+
'age' => null,
186+
'second' => ArrayHash::from([
187+
'city' => '',
188+
]),
189+
]),
190+
]), $form->getValues());
191+
});
192+
193+
194+
test(function () { // onSuccess test
195+
$_SERVER['REQUEST_METHOD'] = 'POST';
196+
197+
$form = createForm();
198+
$form->onSuccess[] = function (Form $form, array $values) {
199+
Assert::same([
200+
'title' => 'sent title',
201+
'first' => [
202+
'name' => '',
203+
'age' => 999,
204+
'second' => [
205+
'city' => 'sent city',
206+
],
207+
],
208+
], $values);
209+
};
210+
211+
$form->onSuccess[] = function (Form $form, ArrayHash $values) {
212+
Assert::equal(ArrayHash::from([
213+
'title' => 'sent title',
214+
'first' => ArrayHash::from([
215+
'name' => '',
216+
'age' => 999,
217+
'second' => ArrayHash::from([
218+
'city' => 'sent city',
219+
]),
220+
]),
221+
]), $values);
222+
};
223+
224+
$form->onSuccess[] = function (Form $form, $values) {
225+
Assert::equal(ArrayHash::from([
226+
'title' => 'sent title',
227+
'first' => ArrayHash::from([
228+
'name' => '',
229+
'age' => 999,
230+
'second' => ArrayHash::from([
231+
'city' => 'sent city',
232+
]),
233+
]),
234+
]), $values);
235+
};
236+
237+
$ok = false;
238+
$form->onSuccess[] = function () use (&$ok) {
239+
$ok = true;
240+
};
241+
242+
$form->fireEvents();
243+
Assert::true($ok);
244+
});

0 commit comments

Comments
 (0)