Skip to content

Commit dcd80e5

Browse files
committed
added Container::setMappedType() and parameter getValues($returnType) for mapping to objects
1 parent 032cf95 commit dcd80e5

File tree

4 files changed

+163
-15
lines changed

4 files changed

+163
-15
lines changed

src/Forms/Container.php

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
namespace Nette\Forms;
1111

1212
use Nette;
13+
use Nette\Utils\ArrayHash;
1314

1415

1516
/**
1617
* Container for form controls.
1718
*
18-
* @property Nette\Utils\ArrayHash $values
19+
* @property ArrayHash $values
1920
* @property-read \Iterator $controls
2021
* @property-read Form|null $form
2122
*/
@@ -35,6 +36,9 @@ class Container extends Nette\ComponentModel\Container implements \ArrayAccess
3536
/** @var bool */
3637
private $validated;
3738

39+
/** @var string */
40+
private $mappedType = ArrayHash::class;
41+
3842

3943
/********************* data exchange ****************d*g**/
4044

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

97101
/**
98102
* Returns the values submitted by the form.
99-
* @return Nette\Utils\ArrayHash|array
103+
* @param string|null $returnType 'array' for array
104+
* @return object|array
100105
*/
101-
public function getValues(bool $asArray = false)
106+
public function getValues($returnType = null)
102107
{
103-
$values = $asArray ? [] : new Nette\Utils\ArrayHash;
108+
$returnType = $returnType
109+
? ($returnType === true ? 'array' : $returnType) // back compatibility
110+
: $this->mappedType;
111+
112+
$isArray = $returnType === 'array';
113+
$obj = $isArray ? new \stdClass : new $returnType;
114+
104115
foreach ($this->getComponents() as $name => $control) {
105116
if ($control instanceof IControl && !$control->isOmitted()) {
106-
$values[$name] = $control->getValue();
107-
117+
$obj->$name = $control->getValue();
108118
} elseif ($control instanceof self) {
109-
$values[$name] = $control->getValues($asArray);
119+
$obj->$name = $control->getValues($isArray ? 'array' : null);
110120
}
111121
}
112-
return $values;
122+
return $isArray ? (array) $obj : $obj;
123+
}
124+
125+
126+
/**
127+
* @return static
128+
*/
129+
public function setMappedType(string $type)
130+
{
131+
$this->mappedType = $type;
132+
return $this;
113133
}
114134

115135

@@ -148,7 +168,7 @@ public function validate(array $controls = null): void
148168
}
149169
foreach ($this->onValidate as $handler) {
150170
$params = Nette\Utils\Callback::toReflection($handler)->getParameters();
151-
$values = isset($params[1]) ? $this->getValues($params[1]->isArray()) : null;
171+
$values = isset($params[1]) ? $this->getValues((string) $params[1]->getType()) : null;
152172
$handler($this, $values);
153173
}
154174
}

src/Forms/Form.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ private function invokeHandlers(iterable $handlers, $button = null): void
416416
{
417417
foreach ($handlers as $handler) {
418418
$params = Nette\Utils\Callback::toReflection($handler)->getParameters();
419-
$values = isset($params[1]) ? $this->getValues($params[1]->isArray()) : null;
419+
$values = isset($params[1]) ? $this->getValues((string) $params[1]->getType()) : null;
420420
$handler($button ?: $this, $values);
421421
if (!$this->isValid()) {
422422
return;

tests/Forms/Container.values.array.phpt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,61 @@ test(function () { // setValues() + array
150150
});
151151

152152

153+
test(function () { // getValues(...arguments...)
154+
$_SERVER['REQUEST_METHOD'] = 'POST';
155+
156+
$form = createForm();
157+
158+
Assert::truthy($form->isSubmitted());
159+
160+
$form->setValues([
161+
'title' => 'new1',
162+
'first' => [
163+
'name' => 'new2',
164+
],
165+
]);
166+
167+
Assert::equal([
168+
'title' => 'new1',
169+
'first' => [
170+
'name' => 'new2',
171+
'age' => '999',
172+
'second' => [
173+
'city' => 'sent city',
174+
],
175+
],
176+
], $form->getValues('array'));
177+
});
178+
179+
180+
test(function () { // setMappedType(array)
181+
$_SERVER['REQUEST_METHOD'] = 'POST';
182+
183+
$form = createForm();
184+
$form->setMappedType('array');
185+
186+
Assert::truthy($form->isSubmitted());
187+
188+
$form->setValues([
189+
'title' => 'new1',
190+
'first' => [
191+
'name' => 'new2',
192+
],
193+
]);
194+
195+
Assert::equal([
196+
'title' => 'new1',
197+
'first' => [
198+
'name' => 'new2',
199+
'age' => '999',
200+
'second' => [
201+
'city' => 'sent city',
202+
],
203+
],
204+
], $form->getValues());
205+
});
206+
207+
153208
test(function () { // onSuccess test
154209
$_SERVER['REQUEST_METHOD'] = 'POST';
155210

tests/Forms/Container.values.mapping.phpt

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,10 @@ test(function () { // submitted form + getValues()
109109
$_SERVER['REQUEST_METHOD'] = 'POST';
110110

111111
$form = createForm();
112+
$form->setMappedType(FormData::class);
113+
112114
Assert::truthy($form->isSubmitted());
113-
Assert::equal(ArrayHash::from([
115+
Assert::equal(hydrate(FormData::class, [
114116
'title' => 'sent title',
115117
'first' => ArrayHash::from([
116118
'name' => '',
@@ -127,12 +129,14 @@ test(function () { // submitted form + reset()
127129
$_SERVER['REQUEST_METHOD'] = 'POST';
128130

129131
$form = createForm();
132+
$form->setMappedType(FormData::class);
133+
130134
Assert::truthy($form->isSubmitted());
131135

132136
$form->reset();
133137

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

151155
$form = createForm();
156+
$form->setMappedType(FormData::class);
157+
152158
Assert::truthy($form->isSubmitted());
153159

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

162-
Assert::equal(ArrayHash::from([
168+
Assert::equal(hydrate(FormData::class, [
163169
'title' => 'new1',
164170
'first' => ArrayHash::from([
165171
'name' => 'new2',
@@ -178,7 +184,7 @@ test(function () { // setValues() + object
178184
]),
179185
]), true);
180186

181-
Assert::equal(ArrayHash::from([
187+
Assert::equal(hydrate(FormData::class, [
182188
'title' => 'new1',
183189
'first' => ArrayHash::from([
184190
'name' => 'new2',
@@ -191,10 +197,64 @@ test(function () { // setValues() + object
191197
});
192198

193199

200+
test(function () { // getValues(...arguments...)
201+
$_SERVER['REQUEST_METHOD'] = null;
202+
203+
$form = createForm();
204+
205+
$form->setValues([
206+
'title' => 'new1',
207+
'first' => [
208+
'name' => 'new2',
209+
],
210+
]);
211+
212+
Assert::equal(hydrate(FormData::class, [
213+
'title' => 'new1',
214+
'first' => ArrayHash::from([
215+
'name' => 'new2',
216+
'age' => null,
217+
'second' => ArrayHash::from([
218+
'city' => '',
219+
]),
220+
]),
221+
]), $form->getValues(FormData::class));
222+
223+
224+
$form->setMappedType(FormData::class);
225+
$form['first']->setMappedType(FormFirstLevel::class);
226+
$form['first-second']->setMappedType(FormSecondLevel::class);
227+
228+
Assert::equal(hydrate(FormData::class, [
229+
'title' => 'new1',
230+
'first' => hydrate(FormFirstLevel::class, [
231+
'name' => 'new2',
232+
'age' => null,
233+
'second' => hydrate(FormSecondLevel::class, [
234+
'city' => '',
235+
]),
236+
]),
237+
]), $form->getValues());
238+
239+
Assert::equal([
240+
'title' => 'new1',
241+
'first' => [
242+
'name' => 'new2',
243+
'age' => null,
244+
'second' => [
245+
'city' => '',
246+
],
247+
],
248+
], $form->getValues(true));
249+
});
250+
251+
194252
test(function () { // onSuccess test
195253
$_SERVER['REQUEST_METHOD'] = 'POST';
196254

197255
$form = createForm();
256+
$form->setMappedType(FormData::class);
257+
198258
$form->onSuccess[] = function (Form $form, array $values) {
199259
Assert::same([
200260
'title' => 'sent title',
@@ -222,7 +282,20 @@ test(function () { // onSuccess test
222282
};
223283

224284
$form->onSuccess[] = function (Form $form, $values) {
225-
Assert::equal(ArrayHash::from([
285+
Assert::equal(hydrate(FormData::class, [
286+
'title' => 'sent title',
287+
'first' => ArrayHash::from([
288+
'name' => '',
289+
'age' => 999,
290+
'second' => ArrayHash::from([
291+
'city' => 'sent city',
292+
]),
293+
]),
294+
]), $values);
295+
};
296+
297+
$form->onSuccess[] = function (Form $form, FormData $values) {
298+
Assert::equal(hydrate(FormData::class, [
226299
'title' => 'sent title',
227300
'first' => ArrayHash::from([
228301
'name' => '',

0 commit comments

Comments
 (0)