Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Symfony 2 support partial form binding?

My question(s):

  1. Does Symfony 2 have support for PATCH requests, or any type of partial form content submissions? If so, is there a "correct" (or, more accurately "preferred") way to do this?

  2. Aside from the PRE_BIND (see below) event approach, are there any other patterns or ways to solve this problem? If there are other ways of solving this problem, are any of them considered better, or worse, than others?

What I've found/done so far: According to a pull request on Github (#5576), work was done to support partial form bindings in Symfony 2 (from my understanding, targeting Symfony 2.2). However, I can't find any documentation or examples outside of that pull request that indicate how to use partial form bindings.

One solution that I've found may suit my purposes. The approach is to attach an event subscriber to the PRE_BIND event for a form type, a cursory search of stackoverflow yielded the following answer which is similar to one I'm currently employing: https://stackoverflow.com/a/11687863/657674.

like image 554
Sean Quinn Avatar asked Nov 05 '13 16:11

Sean Quinn


1 Answers

For PATCH requests, Symfony 2.3 (maybe earlier?) natively supports partial model updates. See explanation below.

For non-PATCH requests (e.g. PUT and POST), you can still perform partial data binding by either creating and registering an event subscriber to manipulate the unsubmitted data to their original values, or you can write a custom request handler to always call the $form->submit() method with $clearMissing set to false.

Handling Partial Binding with PATCH Requests

After digging into the internals of Symfony a little bit more, and coming to a better understanding of event subscribers and form extensions, I stumbled upon the HttpFoundationRequestHandler class. Basically, as of Symfony 2.3, instead of calling $form->submit($request) when binding a form's submitted data developers should be calling $form->handleRequest($request); this invokes the attached request handler (by default HttpFoundationRequestHandler). The request handler does a few things, but most importantly is how it calls $form->submit(). It passes a value of false into the form's submit method if the request method was PATCH telling the form not to bind unsupplied form data as null values.

There are some caveats around using the PATCH method in Symfony 2.3 that can be further explained by Symfony's documentation:

How to use HTTP Methods beyond GET and POST in Routes:

"Unfortunately, life isn't quite this simple, since most browsers do not support sending PUT and DELETE requests. Fortunately Symfony2 provides you with a simple way of working around this limitation. By including a _method parameter in the query string or parameters of an HTTP request, Symfony2 will use this as the method when matching routes."

The above quote from Symfony's documentation explains that most browsers do not support sending PUT, PATCH, or DELETE requests. Which is a problem because for us to leverage Symfony's native support for partial form updates, we need to use a PATCH request. However, Symfony provides an answer to this. The documentation tells us that we can use the _method parameter or form value to spoof the actual request we want and Symfony will know exactly what we mean. For _method to be understood though, you may have to enable the http_method_override configuration option, e.g.:

# config.yml
framework:
    http_method_override: true
    ...

There are also other ways of telling Symfony what method the form should use, and those can be found here: Changing the Action and Method of a Form.

like image 122
Sean Quinn Avatar answered Oct 16 '22 16:10

Sean Quinn