Skip to content

Instantly share code, notes, and snippets.

@bjo3rnf
Last active November 19, 2021 17:19
Show Gist options
  • Star 65 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save bjo3rnf/4061232 to your computer and use it in GitHub Desktop.
Save bjo3rnf/4061232 to your computer and use it in GitHub Desktop.
Hidden field for Symfony2 entities
<?php
namespace Dpn\ToolsBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Dpn\ToolsBundle\Form\DataTransformer\EntityToIdTransformer;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\Common\Persistence\ObjectManager;
class EntityHiddenType extends AbstractType
{
/**
* @var ObjectManager
*/
protected $objectManager;
public function __construct(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new EntityToIdTransformer($this->objectManager, $options['class']);
$builder->addModelTransformer($transformer);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver
->setRequired(array('class'))
->setDefaults(array(
'invalid_message' => 'The entity does not exist.',
))
;
}
public function getParent()
{
return 'hidden';
}
public function getName()
{
return 'entity_hidden';
}
}
<?php
namespace Dpn\ToolsBundle\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
class EntityToIdTransformer implements DataTransformerInterface
{
/**
* @var ObjectManager
*/
protected $objectManager;
/**
* @var string
*/
protected $class;
public function __construct(ObjectManager $objectManager, $class)
{
$this->objectManager = $objectManager;
$this->class = $class;
}
public function transform($entity)
{
if (null === $entity) {
return;
}
return $entity->getId();
}
public function reverseTransform($id)
{
if (!$id) {
return null;
}
$entity = $this->objectManager
->getRepository($this->class)
->find($id);
if (null === $entity) {
throw new TransformationFailedException();
}
return $entity;
}
}
@lughino
Copy link

lughino commented Feb 25, 2013

Great job!
One question, how do I pass the class?

@tfernandez
Copy link

Worked like a charm! Thanks!

Remember add the service in the bundle services.yml to allow use the new field type

services:
 acme_demo.type.entity_hidden:
   class: Acme\DemoBundle\Form\Type\EntityHiddenType
   arguments: ["@doctrine.orm.entity_manager"]
   tags:
   - { name: form.type, alias: entity_hidden }

add the services.yml to the config.yml imports:

 imports:
  - { resource: "@AcmeDemoBundle/Resources/config/services.yml" }

Modify the namespaces to fit with your bundle structure

and just add a new "entity_hidden" field to the form in this way:

    $builder
            ->add('email')
            ->add('name')
            ->add('car', 'entity_hidden', array(
                'class' => 'Acme\DemoBundle\Entity\Car'
            ))

More info about apply the DataTransformer in the symfony2 Docs:

http://symfony.com/doc/current/cookbook/form/data_transformers.html#creating-the-transformer

@lmejiahn
Copy link

lmejiahn commented May 7, 2013

It worked!, thanks @dreipunktnull

Copy link

ghost commented May 11, 2013

It worked for me as well, thanks.

@Tocacar
Copy link

Tocacar commented May 14, 2013

I found this very useful - thanks!

@gffranco
Copy link

Thanks for sharing this, it helped a lot!

@wagnerpinheiro
Copy link

Thanks! very useful...

@igormancos
Copy link

Thanks, is fine!

@alfchee
Copy link

alfchee commented Jan 10, 2014

Do you guess this works the same if I only change the argument for ODM? Meaning, changing this in the configuration of the service: arguments: ["@doctrine.odm.mongodb.document_manager"]

@mdjaman
Copy link

mdjaman commented Feb 9, 2014

Excuse my questions, im new to symfony. How can i pass some options to the form since i used this in controller?

private function createEditForm(Sms $entity)
{
        $form = $this->createForm(new SmsType(), $entity, array(
            'action' => $this->generateUrl('sms_update', array('id' => $entity->getId())),
            'method' => 'PUT',
        ));

        $form->add('submit', 'submit', array('label' => 'Update'));

        return $form;
 }

@bjo3rnf
Copy link
Author

bjo3rnf commented Feb 9, 2014

Wow, I didn't notice all those comments. Thanks and sorry for not answering some of them.

@alfchee: yes, that should work as well.
@mdjaman: what kind of options do you mean?

@mdjaman
Copy link

mdjaman commented Feb 9, 2014

Thx 4 answering. I need to pass user entity

@mdjaman
Copy link

mdjaman commented Feb 9, 2014

Thx found what i was looking for. Thought that only instance of AbstractType could be passed in

$this->createForm('acme_userbundle_sms', $entity, array(
            'action' => $this->generateUrl('sms_create'),
            'method' => 'POST',
        ));
```php
form_name 'acme_userbundle_sms' could be passed. Thks for your time

@mellivora-capensis
Copy link

Thanks, dude =)

@AhmedSamy
Copy link

  • 1 cheers !

@jamogon
Copy link

jamogon commented Mar 5, 2014

Thanks!!! Great Job!!!

If the user doesn't write the class option:

$builder
        ->add('car', 'hidden_entity', array())
;

the class is null and the transformation throws the next error:
Class '' does not exist

If the user uses the method setRequired() in EntityHiddenType file:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver
        ->setRequired(array('class'))
        ->setDefaults(array(
            'invalid_message' => 'The entity does not exist.',
        ))
    ;
}

the application throws a 500 error with the next information:
The required option "class" is missing.

@bjo3rnf
Copy link
Author

bjo3rnf commented Mar 30, 2014

Hi @jamogon,

thanks for the hint. I updated the Gist accordingly. Didn't even know about the setRequired() method of the OptionsResolver.

Cheers
Björn

@skonsoft
Copy link

Great Job !!

Thank you !

Why Symfony community would not integrate this solution. it's very useful !

@webdevilopers
Copy link

👍

Did you ever propose this improvement to Symfony, @bjo3rnf ?

There also seems to be a simple workaround using the property_path:

$builder->add('entity', 'hidden', array('property_path' => 'entity.id'));

as mentioned by @webmozart here:
symfony/symfony#3182

And it looks like it is finally going to make it into symfony here:
symfony/symfony#8293

@neonxp
Copy link

neonxp commented May 25, 2015

Thank you! Works great!

@shakogele
Copy link

How to pass default value to Hidden_entity field? for eg. I have test controller which has field Author. Author I am getting from db after user logs in to system.

@gastoncs
Copy link

How can I set an entity in a onPreSubmit or preSetData and have it attach to the form entity?

@xanaxilovsky
Copy link

Thanks! It helped a lot!

I forked it to make it compatible with symfony 2.8 ( https://gist.github.com/xanou/e630e4e25df60d33b050 )

@runciters
Copy link

Thanks, you made my day!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment