peace_love
peace_love

Reputation: 6461

How can I create a dynamic function that pulls data from mysql database and builds a form in Symfony 4?

I want to build a Controller that will load data from the database and built a form from it, but depending on the slug.

public function form($slug, Request $request){
   $EntityName = 'App\\Entity\\' . ucwords($slug);
   $item= $this->getDoctrine()->getRepository($EntityName)->find($id);
   $form = $this->createFormBuilder($item)

So this means, if the slug is for example products then I want to build a form from my database table `products with all the fields that are inside this table:

So in products I have for example the fields id, name, color. So the output I would need is

  ->add('id', TextType::class, array('attr' => array('class' => 'form-control')))
  ->add('name', TextType::class, array('attr' => array('class' => 'form-control')))
  ->add('color', TextType::class, array('attr' => array('class' => 'form-control')))

But if my slug is for example members and in my members table the fields are id, username, email then a form with this fields should be builded:

 ->add('id', TextType::class, array('attr' => array('class' => 'form-control')))
  ->add('username', TextType::class, array('attr' => array('class' => 'form-control')))
  ->add('email', TextType::class, array('attr' => array('class' => 'form-control')))

The problem for me is now how to create this fields that are depending on the slug. I was thinking to somehow get the fields from the object $item. This is the object $item:

 object(App\Entity\Members)#4788 (6) {
      ["id":"App\Entity\Members":private]=>
      int(9)
      ["username":"App\Entity\Members":private]=>
      string(13) "123"
      ["plainPassword":"App\Entity\Members":private]=>
      NULL
      ["password":"App\Entity\Members":private]=>
      string(0) ""
      ["email":"App\Entity\Members":private]=>
      string(7) "[email protected]"
      ["isActive":"App\Entity\Members":private]=>
      bool(true)
    }

I was trying to work with get_object_vars but this is not working with private objects, so I guess this is not a good solution. I also tried to create an array ($array = (array) $item;) from the object to build the form stucture with foreach. But it does not seem to be the right way neither.

Do you have any experience with functions that are loading data dynamically from database tables and create a form? I am happy for every idea or advice.

Upvotes: 0

Views: 161

Answers (1)

LBA
LBA

Reputation: 4089

You could try something like this

$cmf = $em->getMetadataFactory();
$class = $cmf->getMetadataFor($entityName);

foreach ($class->fieldMappings as $fieldMapping) {
  echo $fieldMapping['fieldName'] . "\n";
}

This will give you all fields for your Entity based on Doctrine's Metadata model.

Check out ClassMetadata API documentation for more information and especially which information you'll get there.

E.g. you could use something like

  • isNullable(string $fieldName) to ensure some 'mandatory validation'
  • getIdentifierColumnNames() to exclude all identifier columns (note: this will return column names not entity fields, but you can easily identify these
  • getTypeOfField to get some hint whether a field is a string or a number (again to allow more specific form attributes)
  • etc... just check the documentation and try it

BUT generally be careful using the ClassMetadata as your use case is not really what it's meant for - but we use it for a similar case as well.

Upvotes: 1

Related Questions