Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My transformer doesn't work ( from model data to form data )

I'm building a silex application (the source is here)
In the App\Form\DataTransformer I have a MetadataTransformer class.
But the transform method doesn't work (the reverse transform does).
It is applied to an App\Form\Metadata AbstractType, which is part of a collection in an App\Form\ArticleForm AbstractType.
The last form is called in the edit method of my App\Controller\Admin\ArticleAdminController

The data transformer is supposed to map a data like this

{"key":"value"}

Into a "form data" like :

[{"name":"key","value":"key"}] 

So it can be displayed as a collection.

Metadata.php

class MetaData extends AbstractType
{
    protected $span4 = "span4";
    protected $span3 = "span3";

    public function buildForm(FormBuilderInterface $builder,array $options)
    {
        $builder
            ->add('name', 'text', array(
                "label" => ' ',
                "attr"  => array(
                    "class"       => $this->span3,
                    "placeholder" => "name"
                )
            ))
            ->add('value', 'text', array(
                'label' => ' ',
                'attr'  => array(
                    "class"       => $this->span4,
                    'placeholder' => 'value'
                )
            ))
        ;
    }

    public function getName()
    {
        return "MetaData";
    }
}

ArticleForm.php

class ArticleForm extends AbstractType
{
    // ...some code...

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new TagsToArrayTransformer();
        $metadataTransformer = new MetadataTransformer();

        $builder->add("title", "text", array(
            "required" => true,
            "attr"     => array(
                "class"       => $this->defaultClass,
                "placeholder" => "The title"
            )
        ));
        $builder->add("content", "textarea", array(
            "attr" => array(
                "placeholder" => "the content",
                "rows"        => 20,
                "class"       => $this->defaultClass
            )
        ));
        $builder->add(
            $builder->create('metadatas', 'collection', array(
                "type"         => new MetaData(),
                'allow_add'    => true,
                'allow_delete' => true,
                'by_reference' => false,
            ))
            ->addModelTransformer($metadataTransformer)
        );

        // ...some code...
    }

    public function getName()
    {
        return "article";
    }
}

My data transformer should look like :

MetadataTransformer.php

namespace App\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;

class MetadataTransformer implements DataTransformerInterface
{
    function transform($metadatas)
    {
        foreach($metadatas as $key => $value) {
            $result[] = array('name' => $key, 'value' => $value);
        }

        return $result;
    }

    function reverseTransform($metadatas)
    {
        if(is_array($metadatas)) {
            foreach($metadatas as $value) {
                $result[$value['name']] = $value['value'];
            }

            return $result;
        }
    }
}

The reverseTransform works, but the transfom itself doesn't seem to.
The goal here is to be able to display a dynamic collection in a form (add and remove metadatas dynamically in my article form page)

In the repo I add to change the code to make it work (i.e. transforming the datas in the controller ArticleAdminController, instead of doing it in the Transformer)
If I log the result of the transform at runtime, the result is what I expect, but the form won't use it.

I tried already the addViewTransformer / addModelTransformer 2.1 api but it did not make any difference.

So how what's wrong with my model data -> to -> form data transform ?

like image 837
mpm Avatar asked Sep 19 '12 10:09

mpm


1 Answers

Your form type is collection and your transformer returns an array. You need to recast it. Try:

namespace App\Form\DataTransformer{
use Symfony\Component\Form\DataTransformerInterface;
class MetadataTransformer implements DataTransformerInterface{

function transform($metadatas){
  foreach($metadatas as $key=>$value):
    $result[]=array('name'=>$key,'value'=>$value);
  endforeach;
  $results=new \Doctrine\Common\Collections\ArrayCollection($result);
  return $results;
}

function reverseTransform($metadatas){
  if(is_array($metadatas)){
    foreach($metadatas as $value){
      $result[$value['name']]=$value['value'];
    }
    return $result;
    }
  }
}
like image 152
Lighthart Avatar answered Nov 01 '22 11:11

Lighthart