From 8945195c31f07f30454b26273ef983e6a24742d4 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Thu, 23 Sep 2021 17:08:20 +0200 Subject: [PATCH] Container::getValues($obj) mapping to PHP 8 constructor --- ecs.php | 1 + src/Forms/Container.php | 14 ++- .../Container.values.mapping-constructor.phpt | 103 ++++++++++++++++++ 3 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 tests/Forms/Container.values.mapping-constructor.phpt diff --git a/ecs.php b/ecs.php index 71d15ee57..8f90b4ecc 100644 --- a/ecs.php +++ b/ecs.php @@ -16,5 +16,6 @@ $parameters->set('skip', [ 'fixtures/*', 'tests/Forms/Container.values.mapping.74.phpt', + 'tests/Forms/Container.values.mapping-constructor.phpt', ]); }; diff --git a/src/Forms/Container.php b/src/Forms/Container.php index 57344d9cd..5d5f8ccc1 100644 --- a/src/Forms/Container.php +++ b/src/Forms/Container.php @@ -138,13 +138,19 @@ public function getUnsafeValues($returnType, array $controls = null) { if (is_object($returnType)) { $obj = $returnType; + $rc = new \ReflectionClass($obj); } else { $returnType = ($returnType ?? $this->mappedType ?? ArrayHash::class); - $obj = $returnType === self::ARRAY ? new \stdClass : new $returnType; + $rc = new \ReflectionClass($returnType === self::ARRAY ? \stdClass::class : $returnType); + if ($rc->hasMethod('__construct') && $rc->getMethod('__construct')->getNumberOfRequiredParameters()) { + $obj = new \stdClass; + $useConstructor = true; + } else { + $obj = $rc->newInstance(); + } } - $rc = new \ReflectionClass($obj); foreach ($this->getComponents() as $name => $control) { $allowed = $controls === null || in_array($control, $controls, true); $name = (string) $name; @@ -163,6 +169,10 @@ public function getUnsafeValues($returnType, array $controls = null) } } + if (isset($useConstructor)) { + return new $returnType(...(array) $obj); + } + return $returnType === self::ARRAY ? (array) $obj : $obj; diff --git a/tests/Forms/Container.values.mapping-constructor.phpt b/tests/Forms/Container.values.mapping-constructor.phpt new file mode 100644 index 000000000..8c0c8988b --- /dev/null +++ b/tests/Forms/Container.values.mapping-constructor.phpt @@ -0,0 +1,103 @@ +addText('title'); + + $first = $form->addContainer('first'); + $first->addText('name'); + $first->addInteger('age'); + + $second = $first->addContainer('second'); + $second->addText('city'); + return $form; +} + + +test('getValues(...arguments...)', function () { + $form = createForm(); + + $form->setValues([ + 'title' => 'new1', + 'first' => [ + 'name' => 'new2', + ], + ]); + + Assert::equal(new FormDataConstruct( + title: 'new1', + first: new FormFirstLevelConstruct( + name: 'new2', + age: null, + second: new FormSecondLevelConstruct( + city: '', + ), + ), + ), $form->getValues(FormDataConstruct::class)); + + $form->setMappedType(FormDataConstruct::class); + $form['first']->setMappedType(FormFirstLevelConstruct::class); + $form['first-second']->setMappedType(FormSecondLevelConstruct::class); + + Assert::equal(new FormDataConstruct( + title: 'new1', + first: new FormFirstLevelConstruct( + name: 'new2', + age: null, + second: new FormSecondLevelConstruct( + city: '', + ), + ), + ), $form->getValues()); +});