Nelmioapidocbundle: "input" does not render API documentation for FormType with DataTransformer - No Errors Thrown ...

Created on 27 Jun 2013  路  10Comments  路  Source: nelmio/NelmioApiDocBundle

Use Case

I have a FormType that requires a user's email address, which is in turn is transformed via a DataTransformer into a User object so it may be bound to the form's data class as a related User. Although the FormType named 'email' is a 'text' FormType, no documentation is generated for this form.

If this requires an enhancement, I'm more than happy to help - however I may need some initial direction.

Also, This is my first time using this bundle, so if I have misunderstood how it is intended to work in this scenario some constructive feedback would be appreciated.

Thank you!

Composer.json:

"require": {
    "symfony/symfony": "2.3.*",
    "jms/serializer-bundle": "0.12.*@dev",
    "friendsofsymfony/rest-bundle": "0.13.*@dev",
    "nelmio/api-doc-bundle": "2.3.*@dev"
},

The Controller:

/**
 * @ApiDoc(
 *      input="Vendor\MainBundle\Form\SystemType"
 * )
 */
public function postSystemAction(Request $request)
{
    $form = $this->createForm(
        new SystemType(),    // FormType
        new System(),                // Entity
        array('entityManager' => $this->getDoctrine()->getManager()) // options
    );

    // Process Stuff ;)
}

The FormType:

class SystemType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new EmailToUserTransformer($options['entityManager']);

        $builder
            ->add(
                $builder->create('email', 'text', array('property_path' => 'user'))
                ->addViewTransformer($transformer)
            )
            ->add('cpuid', 'text', array('required' => true, 'description' => 'The CPU id'))
            ->add('mac_address', 'text', array('required' => true, 'property_path' => 'macAddress'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'        => 'Vendor\MainBundle\Entity\User\System',
            'csrf_protection'   => false
        ));

        $resolver->setRequired(array(
            'entityManager',
        ));

        $resolver->setAllowedTypes(array(
            'entityManager' => 'Doctrine\Common\Persistence\ObjectManager',
        ));
    }

    public function getName()
    {
        return 'vendor_mainbundle_systemtype';
    }
}
bug

Most helpful comment

Hi guys, I've faced the same problem. But looking at how ApiDoc bundle works for few minutes I've found a solution for my case! Here it is:

  1. First, define your form as service, it is pretty easy, suppose it is "form_alias_you_defined"
  2. Inject needed services to form (ex. EntityManager)
  3. Use your form name in ApiDoc instead of form class like this:
/**
* ...
* input = "form_alias_you_defined"
*/

Profit!
Also don't forget to read official documentation with usefull tips, like passing method (GET, POST, etc).

All 10 comments

_bump_
... Hello?

Hi this problem can be solved?

Yes. Here is the recipe:

  1. create a failing test case
  2. fix it!
  3. create a PR

In case 2. does not work for you, jump to 3.

s/In/If/ ?

We experience the exact same problem. Since we had no time to make a good fix we 'quick solved' this by passing the entityManager via a form constructor.

Then you get:

/**
 * @ApiDoc(
 *      input="Vendor\MainBundle\Form\SystemType"
 * )
 */
public function postSystemAction(Request $request)
{
    $form = $this->createForm(
        new SystemType($this->getDoctrine()->getManager()),    // FormType
        new System(),                // Entity
        array() // options
    );
}

And the formType:

class SystemType extends AbstractType
{
      /**
     * @var \Doctrine\ORM\EntityManager
     */
    private $entityManager;

    public function __construct(\Doctrine\ORM\EntityManager $em = null)
    {
        $this->entityManager = $em;
    }   

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new EmailToUserTransformer($this->entityManager);

        $builder
            ->add(
                $builder->create('email', 'text', array('property_path' => 'user'))
                ->addViewTransformer($transformer)
            )
            ->add('cpuid', 'text', array('required' => true, 'description' => 'The CPU id'))
            ->add('mac_address', 'text', array('required' => true, 'property_path' => 'macAddress'))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class'        => 'Vendor\MainBundle\Entity\User\System',
            'csrf_protection'   => false
        ));

        $resolver->setRequired(array(
            'entityManager',
        ));

        $resolver->setAllowedTypes(array(
            'entityManager' => 'Doctrine\Common\Persistence\ObjectManager',
        ));
    }

    public function getName()
    {
        return 'vendor_mainbundle_systemtype';
    }
}

In the EmailToUserTransformer the constructor should be initialized to = null to like this

public function __construct(\Doctrine\ORM\EntityManager $em = null)

It looks like these issues are the same: https://github.com/nelmio/NelmioApiDocBundle/issues/118

yep. duplicate of #118

Hi guys, I've faced the same problem. But looking at how ApiDoc bundle works for few minutes I've found a solution for my case! Here it is:

  1. First, define your form as service, it is pretty easy, suppose it is "form_alias_you_defined"
  2. Inject needed services to form (ex. EntityManager)
  3. Use your form name in ApiDoc instead of form class like this:
/**
* ...
* input = "form_alias_you_defined"
*/

Profit!
Also don't forget to read official documentation with usefull tips, like passing method (GET, POST, etc).

It would be cool to add this documentation.

It would be cool to add this documentation.

Would you mind contribute to the doc? thanks :)

Was this page helpful?
0 / 5 - 0 ratings