Skip to content

Instantly share code, notes, and snippets.

@onema
Forked from makasim/gist:3720535
Last active December 20, 2015 02:59
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save onema/6060077 to your computer and use it in GitHub Desktop.
Save onema/6060077 to your computer and use it in GitHub Desktop.
Form PatchSubsciber for Symfony 2.3. This Form Event Subscriber will help prepare data for a PATCH request. It can be added in your CustomFormType::buildForm method.
<?php
namespace Acme\DemoBundle\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
/**
* Changes Form->submit() behavior so that it treats not set values as if they
* were sent unchanged.
*
* Use when you don't want fields to be set to NULL when they are not displayed
* on the page (or to implement PUT/PATCH requests).
* @link https://gist.github.com/makasim/3720535 for more information
*/
class PatchSubscriber implements EventSubscriberInterface
{
public function onPreSubmit(FormEvent $event)
{
$form = $event->getForm();
$clientData = $event->getData();
$clientData = array_replace($this->prepareData($form), $clientData ?: array());
$event->setData($clientData);
}
/**
* Returns the form's data like $form->submit() expects it
*/
protected function prepareData($form)
{
if ($form->count()) {
$data = array();
foreach ($form->all() as $name => $child) {
$data[$name] = $this->prepareData($child);
}
return $data;
} else {
return $form->getViewData();
}
}
static public function getSubscribedEvents()
{
return array(
FormEvents::PRE_SUBMIT => 'onPreSubmit',
);
}
}
@onema
Copy link
Author

onema commented Jul 24, 2013

To use this code add the event subscriber in your custom form type like this:

<?php 
// Acme/DemoBundle/Form/Type/CustomFormType.php
namespace Acme\DemoBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class CustomFormType extends AbstractType
{
    // ...

    public function buildForm(FormBuilderInterface $builder, array $options) 
    {
        // your logic here ...

        if($options['method'] === 'PATCH') {
            // Event Subscriber to prepare the submitted data for a PATCH
            $builder->addEventSubscriber(new PatchSubscriber());
        }
    }
}

Copy link

ghost commented Jan 21, 2014

Hey, thank you for the patch. $options['method'] is always "POST" here. Nevertheless, I kicked this condition, because I dont need it. Thanks again.

@glucazeau
Copy link

Hi, thank you for this patch it's been very useful. However, I've had a little problem with boolean field, rendered as a checkbox. When unchecked, to set the field to false, it's considered empty and then replaced by the patch and set to true. Am I missing somehting, how can I deal with that?

Thank you

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