Skip to content

Commit 2f97c6a

Browse files
committed
feat: Support specifying type of data_class in forms
1 parent 58e64ff commit 2f97c6a

File tree

10 files changed

+156
-3
lines changed

10 files changed

+156
-3
lines changed

extension.neon

+3
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ parameters:
3434
- stubs/Symfony/Component/EventDispatcher/EventDispatcherInterface.stub
3535
- stubs/Symfony/Component/EventDispatcher/EventSubscriberInterface.stub
3636
- stubs/Symfony/Component/EventDispatcher/GenericEvent.stub
37+
- stubs/Symfony/Component/Form/AbstractType.stub
3738
- stubs/Symfony/Component/Form/ChoiceList/Loader/ChoiceLoaderInterface.stub
3839
- stubs/Symfony/Component/Form/Exception/ExceptionInterface.stub
3940
- stubs/Symfony/Component/Form/Exception/RuntimeException.stub
4041
- stubs/Symfony/Component/Form/Exception/TransformationFailedException.stub
4142
- stubs/Symfony/Component/Form/DataTransformerInterface.stub
4243
- stubs/Symfony/Component/Form/FormBuilderInterface.stub
4344
- stubs/Symfony/Component/Form/FormInterface.stub
45+
- stubs/Symfony/Component/Form/FormFactoryInterface.stub
4446
- stubs/Symfony/Component/Form/FormTypeExtensionInterface.stub
4547
- stubs/Symfony/Component/Form/FormTypeInterface.stub
4648
- stubs/Symfony/Component/Form/FormView.stub
@@ -50,6 +52,7 @@ parameters:
5052
- stubs/Symfony/Component/HttpFoundation/Session.stub
5153
- stubs/Symfony/Component/Messenger/StampInterface.stub
5254
- stubs/Symfony/Component/Messenger/Envelope.stub
55+
- stubs/Symfony/Component/OptionsResolver/Exception/InvalidOptionsException.stub
5356
- stubs/Symfony/Component/OptionsResolver/Options.stub
5457
- stubs/Symfony/Component/Process/Process.stub
5558
- stubs/Symfony/Component/PropertyAccess/PropertyPathInterface.stub
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Symfony\Component\Form;
4+
5+
/**
6+
* @template TData
7+
*
8+
* @implements FormTypeInterface<TData>
9+
*/
10+
abstract class AbstractType implements FormTypeInterface
11+
{
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Symfony\Component\Form;
4+
5+
use Symfony\Component\Form\Extension\Core\Type\FormType;
6+
7+
interface FormFactoryInterface
8+
{
9+
/**
10+
* @template TFormType of FormTypeInterface<TData>
11+
* @template TData
12+
*
13+
* @param class-string<TFormType> $type
14+
* @param TData $data
15+
* @param array<string, mixed> $options
16+
*
17+
* @phpstan-return FormInterface<TData>
18+
*
19+
* @throws \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
20+
*/
21+
public function create(string $type = FormType::class, $data = null, array $options = []): FormInterface;
22+
23+
/**
24+
* @template TFormType of FormTypeInterface<TData>
25+
* @template TData
26+
*
27+
* @param class-string<TFormType> $type
28+
* @param TData $data
29+
* @param array<string, mixed> $options
30+
*
31+
* @phpstan-return FormInterface<TData>
32+
*
33+
* @throws \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
34+
*/
35+
public function createNamed(string $name, string $type = FormType::class, $data = null, array $options = []): FormInterface;
36+
}

stubs/Symfony/Component/Form/FormInterface.stub

+8-3
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
namespace Symfony\Component\Form;
44

55
/**
6-
* @extends \ArrayAccess<string, \Symfony\Component\Form\FormInterface>
7-
* @extends \Traversable<string, \Symfony\Component\Form\FormInterface>
6+
* @template TData
7+
*
8+
* @extends \ArrayAccess<string, \Symfony\Component\Form\FormInterface<mixed>>
9+
* @extends \Traversable<string, \Symfony\Component\Form\FormInterface<mixed>>
810
*/
911
interface FormInterface extends \ArrayAccess, \Traversable, \Countable
1012
{
11-
13+
/**
14+
* @return TData
15+
*/
16+
public function getData();
1217
}

stubs/Symfony/Component/Form/FormTypeExtensionInterface.stub

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace Symfony\Component\Form;
44

5+
/**
6+
* @template TData
7+
*/
58
interface FormTypeExtensionInterface
69
{
710
/**
@@ -10,11 +13,13 @@ interface FormTypeExtensionInterface
1013
public function buildForm(FormBuilderInterface $builder, array $options): void;
1114

1215
/**
16+
* @phpstan-param FormInterface<TData> $form
1317
* @param array<string, mixed> $options
1418
*/
1519
public function buildView(FormView $view, FormInterface $form, array $options): void;
1620

1721
/**
22+
* @phpstan-param FormInterface<TData> $form
1823
* @param array<string, mixed> $options
1924
*/
2025
public function finishView(FormView $view, FormInterface $form, array $options): void;

stubs/Symfony/Component/Form/FormTypeInterface.stub

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace Symfony\Component\Form;
44

5+
/**
6+
* @template TData
7+
*/
58
interface FormTypeInterface
69
{
710
/**
@@ -10,11 +13,13 @@ interface FormTypeInterface
1013
public function buildForm(FormBuilderInterface $builder, array $options): void;
1114

1215
/**
16+
* @phpstan-param FormInterface<TData> $form
1317
* @param array<string, mixed> $options
1418
*/
1519
public function buildView(FormView $view, FormInterface $form, array $options): void;
1620

1721
/**
22+
* @phpstan-param FormInterface<TData> $form
1823
* @param array<string, mixed> $options
1924
*/
2025
public function finishView(FormView $view, FormInterface $form, array $options): void;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Symfony\Component\OptionsResolver\Exception;
4+
5+
class InvalidOptionsException extends \InvalidArgumentException
6+
{
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Stubs\Symfony\Component\Form;
6+
7+
class DataClass
8+
{
9+
/**
10+
* @var int
11+
*/
12+
public $foo;
13+
14+
/**
15+
* @var string
16+
*/
17+
public $bar;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Stubs\Symfony\Component\Form;
4+
5+
use Symfony\Component\Form\AbstractType;
6+
use Symfony\Component\Form\Extension\Core\Type\NumberType;
7+
use Symfony\Component\Form\Extension\Core\Type\TextType;
8+
use Symfony\Component\Form\FormBuilderInterface;
9+
use Symfony\Component\OptionsResolver\OptionsResolver;
10+
11+
/**
12+
* @extends AbstractType<DataClass>
13+
*/
14+
class DataClassType extends AbstractType
15+
{
16+
public function buildForm(FormBuilderInterface $builder, array $options): void
17+
{
18+
$builder
19+
->add('foo', NumberType::class)
20+
->add('bar', TextType::class)
21+
;
22+
}
23+
24+
public function configureOptions(OptionsResolver $resolver): void
25+
{
26+
$resolver
27+
->setDefaults([
28+
'data_class' => DataClass::class,
29+
])
30+
;
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Stubs\Symfony\Component\Form;
4+
5+
use Symfony\Component\Form\FormFactoryInterface;
6+
7+
class FormFactoryAwareClass
8+
{
9+
/**
10+
* @var FormFactoryInterface
11+
*/
12+
private $formFactory;
13+
14+
public function __construct(
15+
FormFactoryInterface $formFactory
16+
) {
17+
$this->formFactory = $formFactory;
18+
}
19+
20+
public function doSomething(): void
21+
{
22+
$form = $this->formFactory->create(DataClassType::class, new DataClass());
23+
$data = $form->getData();
24+
$this->thisOnlyAcceptsDataClass($data);
25+
}
26+
27+
private function thisOnlyAcceptsDataClass(DataClass $data): void
28+
{
29+
}
30+
}

0 commit comments

Comments
 (0)