Skip to content

Commit 4d2743d

Browse files
committed
feature #301 [FORM] Modify make:form to allow non-entities (ckrack)
This PR was squashed before being merged into the 1.0-dev branch (closes #301). Discussion ---------- [FORM] Modify make:form to allow non-entities Before this modification the make:form command allowed passing a fully specified classname. It would generate a form with the correct bound class, but not read the fields. It generated a form with one "field_name" field instead of something more useful. This also affects DTOs. This modification makes our lives easier by reading all fields of the bound class, except the id field. Commits ------- b753768 [FORM] Modify make:form to allow non-entities
2 parents bff1153 + b753768 commit 4d2743d

File tree

5 files changed

+136
-0
lines changed

5 files changed

+136
-0
lines changed

src/Maker/MakeForm.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Bundle\MakerBundle\Generator;
1919
use Symfony\Bundle\MakerBundle\InputConfiguration;
2020
use Symfony\Bundle\MakerBundle\Str;
21+
use Symfony\Bundle\MakerBundle\Util\ClassDetails;
2122
use Symfony\Bundle\MakerBundle\Validator;
2223
use Symfony\Component\Console\Command\Command;
2324
use Symfony\Component\Console\Input\InputArgument;
@@ -95,6 +96,9 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
9596

9697
if (null !== $doctrineEntityDetails) {
9798
$formFields = $doctrineEntityDetails->getFormFields();
99+
} else {
100+
$classDetails = new ClassDetails($boundClassDetails->getFullName());
101+
$formFields = $classDetails->getFormFields();
98102
}
99103

100104
$boundClassVars = [

src/Util/ClassDetails.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\Util;
13+
14+
/**
15+
* @internal
16+
*/
17+
final class ClassDetails
18+
{
19+
private $fullClassName;
20+
21+
public function __construct(string $fullClassName)
22+
{
23+
$this->fullClassName = $fullClassName;
24+
}
25+
26+
/**
27+
* Get list of property names except "id" for use in a make:form context.
28+
*
29+
* @return array|null
30+
*/
31+
public function getFormFields(): array
32+
{
33+
$properties = $this->getProperties();
34+
35+
return array_diff($properties, ['id']);
36+
}
37+
38+
private function getProperties(): array
39+
{
40+
$reflect = new \ReflectionClass($this->fullClassName);
41+
$props = $reflect->getProperties();
42+
43+
$propertiesList = [];
44+
45+
foreach ($props as $prop) {
46+
$propertiesList[] = $prop->getName();
47+
}
48+
49+
return $propertiesList;
50+
}
51+
}

tests/Maker/FunctionalTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,16 @@ public function getCommandTests()
188188
])
189189
->addExtraDependencies('orm')
190190
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeFormForEntity')
191+
];
192+
193+
yield 'form_for_non_entity_dto' => [MakerTestDetails::createTest(
194+
$this->getMakerInstance(MakeForm::class),
195+
[
196+
// Entity name
197+
'TaskType',
198+
'\\App\\Form\\Data\\TaskData',
199+
])
200+
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeFormForNonEntityDto')
191201
];
192202

193203
yield 'form_for_sti_entity' => [MakerTestDetails::createTest(
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace App\Form\Data;
13+
14+
/**
15+
* Data transfer object for Task.
16+
*/
17+
class TaskData
18+
{
19+
public $task;
20+
21+
public $dueDate;
22+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace App\Tests;
13+
14+
use App\Form\Data\TaskData;
15+
use App\Form\TaskType;
16+
use Symfony\Component\Form\Test\TypeTestCase;
17+
18+
class GeneratedFormTest extends TypeTestCase
19+
{
20+
public function testGeneratedForm()
21+
{
22+
$dateTimeObject = new \DateTime();
23+
24+
$formData = [
25+
'task' => 'Acme',
26+
'dueDate' => $dateTimeObject,
27+
];
28+
29+
$objectToCompare = new TaskData();
30+
31+
$form = $this->factory->create(TaskType::class, $objectToCompare);
32+
$form->submit($formData);
33+
34+
$object = new TaskData();
35+
$object->task = 'Acme';
36+
$object->dueDate = $dateTimeObject;
37+
38+
$this->assertTrue($form->isSynchronized());
39+
$this->assertEquals($object, $objectToCompare);
40+
$this->assertEquals($object, $form->getData());
41+
42+
$view = $form->createView();
43+
$children = $view->children;
44+
45+
foreach (array_keys($formData) as $key) {
46+
$this->assertArrayHasKey($key, $children);
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)