symfony / maker-bundle

Symfony Maker Bundle
https://symfony.com/
MIT License
3.34k stars 406 forks source link

make:form and make:crud don't inject typeFields of entity in form's template #472

Open Nico2i opened 4 years ago

Nico2i commented 4 years ago

Good morning !

I want to automate more my developments in Symfony 4. For that, I wanted to fork the maker-bundle and inject in the template Type.tpl.php the typeFields. However, this is already coded but the result is always : ->add('myAttibute') and not ->add('myAttibute', fieldType::class, ...) However, there are this lines in the code (src/Resources/skeleton/crud/form/Type.tpl.php):

public function buildForm(FormBuilderInterface $builder, array $options) { $builder <?php foreach ($form_fields as $form_field => $typeOptions): ?> <?php if (null === $typeOptions['type'] && !$typeOptions['options_code']): ?> ->add('<?= $form_field ?>') <?php elseif (null !== $typeOptions['type'] && !$typeOptions['options_code']): ?> ->add('<?= $form_field ?>', <?= $typeOptions['type'] ?>::class) <?php else: ?> ->add('<?= $form_field ?>', <?= $typeOptions['type'] ? ($typeOptions['type'].'::class') : 'null' ?>, [ <?= $typeOptions['options_code']."\n" ?> ]) <?php endif; ?> <?php endforeach; ?> ; }

Thank you for yours answers. Have a nice day !

LeJeanbono commented 4 years ago

Hi ! Can you give us your entity please ?

Nico2i commented 4 years ago

For example, if I generate an entity from the command make:entity Sport, I have this file : `<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**

I migrate the database , then I generate crud from the make:crud command, I obtain this code

`<?php

namespace App\Form;

use App\Entity\Sport; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver;

class SportType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('nom') ; }

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Sport::class,
    ]);
}

}`

LeJeanbono commented 4 years ago

$nom is type string so you don't need to put TextType::class as type because it's the default value.

Nico2i commented 4 years ago

Thanks, i think I understand ! BUT which are the default values of fields in symfony (string, datetime,... ??) ? We use and need the array of options of the fields to configure them, like that :

-> add('nom', type, array(options))

Where do the options come (when we use the make:entity) ? Do we pass them in arguments, or the generator take them in the annotations like the type ? According to the code, it takes them in the $typeOptions['option_code'], but i can't manage to find where comes this array ?

I have implemented certain functions to meet our needs but i want to understand where the informations come from...

According to github, Do you really come from Rennes ? If it's true, it's really funny, i come from Saint-Brieuc.... ^^

ckrack commented 4 years ago

@Nico2i Symfony uses a FormTypeguesser, for example the DoctrineOrmTypeGuesser from the doctrine-bridge when the type is not specified.

The FormTypeRenderer tries to read the type from typeOptions, which is returned from Symfony\Bundle\MakerBundle\Doctrine\EntityDetails::getFormFields(). However, this never returns an array like the one that seems to be expected.

I never seem to be able to generate a form with make:form or make:crud that contains any types, so the formBuilder only builds on names (and the above mentioned FormTypeGuesser is in place). Nut sure when the types should be added, but maybe we should add some tests to this. The code to add types is present in src/Resources/skeleton/form/Type.tpl.php. Also related to #314

tom-combet commented 2 years ago

Yep, I have the same issue. Looks like the code to add types in src/Resources/skeleton/form/Type.tpl.php is dead code atm.

In fact, $fieldTypeOptions is always null in make:form (see getFormFields methods from EntityDetails class and from ClassDetails class).