Skip to content

Instantly share code, notes, and snippets.

@makasim
Last active June 26, 2017 06:32
Show Gist options
  • Save makasim/3720535 to your computer and use it in GitHub Desktop.
Save makasim/3720535 to your computer and use it in GitHub Desktop.
form partial bind
<?php
namespace Foo\CoreBundle\Form\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormInterface;
/**
* Changes Form->bind() 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).
*/
class PatchSubscriber implements EventSubscriberInterface
{
/**
* @param \Symfony\Component\Form\FormEvent $event
*/
public function onPreBind(FormEvent $event)
{
$clientData = $event->getData();
$unbindClientData = $this->unbind($event->getForm());
if (is_array($unbindClientData)) {
$clientData = array_replace($unbindClientData, $clientData ?: array());
}
$event->setData($clientData);
}
/**
* Returns the form's data like $form->bind() expects it
*
* @return mixed
*/
protected function unbind(FormInterface $form)
{
if (count($form) > 0) {
$clientData = array();
foreach ($form as $name => $childForm) {
$clientData[$name] = $this->unbind($childForm);
}
return $clientData;
}
return $form->getViewData();
}
/**
* @return string[]
*/
static public function getSubscribedEvents()
{
return array(
FormEvents::PRE_BIND => 'onPreBind',
);
}
}
@onema
Copy link

onema commented Jul 23, 2013

Thank you, this gist has been quite useful!

I have updated the code to be compatible with Symfony 2.3. Checkout the code here

@phiamo
Copy link

phiamo commented Dec 13, 2013

perfect thanks a lot!

Copy link

ghost commented Mar 15, 2014

Nice works. Unfortunately the subscriber doesnt works for unmapped form fields.

$builder->add('foo', null, array(
    'description' => 'The foo',
    'mapped'      => false,
    'constraints' => array(
        new NotBlank(array(
            'message' => 'system.error.alert.null'
        ))
    )
));

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