Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2 form to JSON structure

How can the Symfony2 form be transformed to JSON data structure? Looking for proper bundle gave me no results;

Example:

$builder
    ->add('name', 'text')
    ->add('password', 'password')
;

Would result in something like that:

{
    fields: {
        name: {
            type: 'text'
        },
        password: {
            type: 'password'
        }
    }
}

Iterating over each element in form after $form = $this->createForm(new FormType(), new Entity()) was not helpful, could not find some properties that could be defined in form builder.

like image 484
andrius.k Avatar asked Dec 18 '22 23:12

andrius.k


1 Answers

I assume that you want to get this information in a controller once you have posted the form, in which case you can easily get the underlying entity from the form object, like so:

$entity = $form->getData();

At this point you can either manually pull out the fields you want into an array and json_encode() that, or... implement the JsonSerializable interface in your entity and then directly json_encode() the object itself.

For example:

<?php

namespace FooApp/BarBundle/Entity;

use JsonSerializable;

class Baz implements JsonSerializable
{
    private $name;
    private $password;

    // ...

    function jsonSerialize()
    {
        return [
            'fields' => [
                'name'     => ['type' => $this->name],
                'password' => ['type' => $this->password],
            ],
        ];
    }
}

Then, in your controller:

$entity = $form->getData();
$json = json_encode($entity);

Calling json_encode() will automatically invoke Baz::jsonSerialize() and return the array structure you defined, which in turn is JSON-encoded.

Update 2016-06-23

I happened across this question again by chance - and... I realise that I didn't answer your actual question.

You didn't want to convert the form's underlying entity to JSON - instead you want to represent form structure as data. My apologies for misunderstanding - hopefully I can rectify that with an update.

This is a proof-of-concept that should work for a non-nested form (although it should be straightforward to create a recursive version or something for that case). But, assuming a scenario where you have instantiated a form, comprising of fields name and password, like so:

$form = $this->createForm(FooType::class, $foo);

It should then possible to iterate over the instance and derive a representation of the structure; e.g:

$fields = ['fields' => []];

foreach ($form->all() as $field) {
    $name = $field->getName();
    $type = $field->getConfig()->getType()->getBlockPrefix();
    $fields['fields'][$name] = ['type' => $type];
}

echo json_encode($fields, JSON_PRETTY_PRINT);

Yields:

{
    "fields": {
        "name": {
            "type": "text"
        },
        "password": {
            "type": "password"
        }
    }
}

Hope this helps :)

like image 66
Darragh Enright Avatar answered Dec 21 '22 12:12

Darragh Enright