-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Form] Simplify request handling #5493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Do In the example a lookup for block |
@havvg Probably no, for performance reasons. Needs more research though. |
Thinking a bit further, this could also be supported for plain PHP without HttpFoundation: <?php
// will automatically bind $_POST[$form->getName()] if set
$form = $this->createForm('my_form', null, array(
'action' => $this->generateUrl('process_form'),
'method' => 'POST',
));
// BC behavior by dropping "method"
$form = $this->createForm('my_form', null, array(
'action' => $this->generateUrl('process_form'),
));
// BC behavior by unsetting "auto_bind"
$form = $this->createForm('my_form', null, array(
'action' => $this->generateUrl('process_form'),
'method' => 'POST',
'auto_bind' => false,
)); |
This looks great! Both alternatives are some nice shortcuts, my first impression was "alternative 1 is too magic", but if I look at it like "when using the auto_bind option, having a boundable form is the first condition for its validity", then alternative 1 makes sense to me. I can see the submit button isn't rendered by form_end, will it only render the closing form tag? If so, I don't understand why we would need this helper. |
For symmetry, simply. If you'd write out |
We could also do |
Wouldn't that suppose to put the submit button in form_end? |
No, otherwise people couldn't freely place the submit button anymore. |
Hum then I think I'm missing something... Usually isn't the submit button rendered between form_rest and the closing form tag? So if form_rest is done within form_end, when using form_end, how can we render the submit button between them? |
The order of the submit button and |
I really like the idea of having the action url generated by the controller, this way the controller which is already handling the form creation and binding is also responsible for pointing creation to binding. I prefer option 2 with explicit binding, this way there is no ambiguity about when the form is bonded. I don't like the idea when automatically using the $_POST variable. It looks dirty and HttpFundation is here for that. Not injecting the bonded data is really against the whole DI/IOC precept. Finally, I like the idea of I just want to make a proposal for another syntax that looks cleaner to me:
I a not sure here that the use of a |
In general I like these shortcuts. I prefer alternative 2 because its more explicit. I already see developer issues with alternative 1 that could arise, which would be wrong:
Furthermore, I think it should be possible to disable auto-rendering of
|
This is only half-true. From the Form components POV, HttpFoundation is optional, not mandatory. Features supported with HttpFoundation should, if possible, also be supported if not using HttpFoundation. |
@Tobion Valid points. I guess |
@michelsalib I like your Twig syntax. I think it makes sense. Form theming could also be integrated there.
|
The form tag makes sense semantically, as a good twig editor would recognize a missing endtag (in contrast to Another idea: |
The matter is the '{%' is about logic, not about display... Michel Salib De : Tobias Schultze
Reply to this email directly or view it on GitHub: |
@michelsalib Yes, then your own suggestion is not valid. |
That is what bothered me at the beginning. It has the advantage of syntactically enforce the use of a 'endform' keyword. Michel Salib De : Tobias Schultze @michelsalib Yes, then your own suggestion is not valid. Reply to this email directly or view it on GitHub: |
Indeed @Tobion has a good use case against alternative 1. Then what about making $form->isValid() return null when it is not bound? This would require a strict compare when checking for an invalid form, but I don't think it's such a common use case, usually you want to do something when the form is valid, I can't even see any example checking for an invalid form in the docs. Furthermore, if by default (so for most people) forms are auto-bounded, the binding would become an internal stuff, then calling a method named isBound is also missleading, because this binding notion doesn't appear anywhere else in the framework userland code. |
I thought about that too. One solution would be to deprecate the notion "bind" and rename it to "submit", but that's a very delicate topic. I'm not sure how such a deprecation would be received. <?php
if ($form->isSubmitted() && $form->isValid()) {
}
// or
if ($form->isSubmitted()) {
if ($form->isValid()) {
} else {
}
}
// or
$form->submit($request);
// or
$form->submit($_POST[$form->getName()]); |
Indeed that's a huge deprecation... I think it's really explicit to check (isSubmitted) but weird when binding, $form->submit() makes me think to a crawler or something like that. But are you against making isValid return null when the form is not bound? I really find alternative 1 simple and powerful. |
Yes. It really hides what is going on. Having two separate checks for these separate conditions is much easier to read IMHO. |
Follow-up thoughts: Automatically binding a form is hard, because it is difficult to determine which form should be automatically bound (which is the root form?). An alternative is an explicitly called Resulting API: <?php
$form = $this->createForm('my_form', null, array(
'action' => $this->generateUrl('process_form'),
'method' => 'POST',
));
// with HttpFoundation
$form->handleRequest($request);
// without HttpFoundation (uses superglobals)
$form->handleRequest();
if ($form->isSubmitted() && $form->isValid()) {
// do stuff
} |
Btw, IMO the term |
Maybe handleRequest could return wether or not the request has been handled? <?php
$form = $this->createForm('my_form', null, array(
'action' => $this->generateUrl('process_form'),
'method' => 'POST',
));
if ($form->handleRequest($request) && $form->isValid()) {
// do stuff
} |
What about: if ($form->isValid($request)) {
// ...
} ? |
@Trainmaster |
We could also shorten // with HttpFoundation
if ($form->handle($request)->isValid()) {
...
}
// without HttpFoundation
if ($form->handle()->isValid()) {
...
} or // with HttpFoundation
if ($form->process($request)->isValid()) {
...
}
// without HttpFoundation
if ($form->process()->isValid()) {
...
} |
@bschussek : you were saying you wanted to keep 2 different methods in order to check if the form is submitted and if it's valid, instead of delegating both to |
@bamarni We can have these two methods. For the majority of cases it might be easier to just call |
you're right, I also think most of the times |
|
I may be late to the party here, but I'm not sure about the Also, I may be using this wrong, but in some instances I bind a form using GET and POST data alike, except I disable all validation for GET requests. This way, 3rd parties can link to a form with data already pre-filled in the URL, but no errors are rendered in the view. To save the form, a POST (+ validation) is still required. |
@ericclemmons Caling Option 1: Submit manually, you must pass an array or a simple value to submit (as provided by the HTTP client) if (/* submitted */) {
$form->submit(array(...));
$form->submit($_POST[$form->getName()]);
$form->submit($request->request->get($form->getName()));
if ($form->isValid()) {
// ...
}
} Option 2: Let Symfony deal with the above. if ($form->process()->isValid()) {
// ...
}
if ($form->process($request)->isValid()) {
// ...
}
// or, if you want to check submission too
if ($form->process()->isSubmitted()) {
// ...
if ($form->isValid()) {
// ...
}
} This will refer the processing to an internal component, such as |
I also wanted to add some thoughts on this rename from Coming from a ZF1.x background myself, it makes sense to I think Option 1 makes sense when POSTing & subsequently saving a form. Assuming that there would be a However, Option 2 is more vague, which would allow, in my case, a GET request to be "bound", but validation ignored, while a POST request would be bound and validated, and a PATCH request would be bound & validated but with I hope this feedback helps! |
@ericclemmons Both of these options would be supported. If you don't care about the details, you'll use Option 2. And if you want to do specific stuff, you will do Option 1. |
I updated the code sample in the previous comment to be clearer. |
This PR was merged into the master branch. Discussion ---------- [2.3] [Form] Implemented form processors Bug fix: no Feature addition: yes Backwards compatibility break: no Symfony2 tests pass: yes Fixes the following tickets: partially #5493 Todo: - License of the code: MIT Documentation PR: symfony/symfony-docs#2092 Commits ------- 11fee06 [TwigBridge] Removed duplicate entries from the CHANGELOG 68f360c [Form] Moved upgrade nodes to UPGRADE-3.0 01b71a4 [Form] Removed trigger_error() for deprecations as of 3.0 81f8c67 [Form] Implemented form processors 0ea75db [Form] Improved FormRenderer::renderBlock() to be usable outside of form blocks
This PR was merged into the master branch. Discussion ---------- [Form] Deprecated bind() and isBound() in favor of submit() and isSubmitted() | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | yes (*) | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #5493 | License | MIT | Doc PR | TODO This change was discussed for a while in #5493. **(*)** It breaks BC *only for people who implemented* `FormInterface` *manually* (not a lot, so I hope). These can fix the problem by simply renaming `bind()` and `isBound()` in their implementation to `submit()` and `isSubmitted()`. The main rationale is that with the request handlers introduced in #6522, people won't be confronted with the term "binding" anymore. As such, `isBound()` will be a very strange name to new users that have never used `bind()` manually. See this code sample as example: ```php $form = $this->createForm(...); $form->handleRequest($request); // Imagine you have never heard about bind() or binding. What does this mean? if ($form->isBound()) { // ... } ``` In reality, `bind()` submits a form. Where-ever I renamed "bind" to "submit" in the comments, "submit" made actually much more sense. So it does in the code sample above: ```php $form = $this->createForm(...); $form->handleRequest($request); // Aha! if ($form->isSubmitted()) { // ... } ``` Also when using `submit()` directly, the code makes much more sense now: ```php $text = $this->createForm('text'); $text->submit('New Value'); ``` For current users, the current naming will be supported until 3.0. Commits ------- 41b0127 [Form] Deprecated bind() and isBound() in favor of submit() and isSubmitted()
Closed in favor of #9032. |
We could simplify the form request handling by
We previously had this idea and dropped it. I was inspired again by Zend Framework 2's API and thought that it might be a good idea. Kudos to them.
Proposed simplification (fully BC):
Note that the check for
$request->getMethod()
is not necessary anymore in the above snippet. Also,bind($request)
is done implicitely by passing the "request" option (explicit binding is also possible, of course).Thoughts? Preferences for Alternative 1 or 2?
The text was updated successfully, but these errors were encountered: