Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Form] Add ability to clear form errors#27580

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
fabpot merged 1 commit intosymfony:masterfromcolinodell:feature/clearable-forms
Jun 25, 2018

Conversation

@colinodell
Copy link
Contributor

@colinodellcolinodell commentedJun 11, 2018
edited
Loading

QA
Branch?master
Bug fix?no
New feature?yes
BC breaks?no
Deprecations?no
Tests pass?yes
Fixed tickets#14060
LicenseMIT
Doc PRsymfony/symfony-docs#9916

This PR adds the ability to manually clear form errors, thus improving the DX issue reported in#14060.

Unlike my original approach in#14233 and#27571 which break BC, this adds a newClearableErrorInterface whichForm implements. (Button does not implement it because buttons can't have errors.)

yceruto, jshenk, jgerringer, mcurtin, chrissnyder2337, jpmc, jonnyeom, andrewadcock, vudaltsov, lenybernard, and 3 more reacted with thumbs up emoji
*
* @return $this
*/
publicfunctionclearErrors($deep =false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Couldtrue be a better default here? How frequent is to clear errors for root form only? I think most of the time it happens inside a child field.

There is an issue about the same default butgetErrors($deep = false) method#25738 and was reported as confusing.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't have a strong preference either way, but I do think the default value here should matchgetErrors().

chrissnyder2337, jpmc, and vudaltsov reacted with thumbs up emoji
@TerjeBr
Copy link

TerjeBr commentedJun 12, 2018
edited
Loading

I have now thought about this, what about adding aFormExtendedInterface that extends bothFormInterface andClearableErrorInterface? The use case for the interface after all is to have a way to pass around form objects to functions and methods, and then you want an all inclusive interface that can cover all the methods implemented in theForm class. What do you think?

// Clear errors from children
foreach ($thisas$child) {
if ($childinstanceof ClearableErrorInterface) {
$child->clearErrors(true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Is it possible to have a clearable form type nested in a non-clearable one?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yes, buttons are not clearable and they could be included in a form that is clearable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The question was the other way round. As the code here stops the traversal of the form tree as soon as a non-clearable form type is encountered, it will not clear clearable fields nested in non-clearable ones.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The only non-clearable fields we have in the symfony core are buttons that can't have children.

This could append in libraries but then it can be considered the responsibility of the library to implement this interface if needed.

colinodell reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yeah, I know. But why risk it, if the change would be fairly easy?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

It would mean children won't be able to implement custom error cleaning logic, that's something someone might want to do.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yeah, I know. But why risk it, if the change would be fairly easy?

We can't addclearErrors() toFormInterface as that would be a BC break. And even if we could, that would require us to implementclearErrors() on theButton class, which makes no sense because buttons can't have errors or children - it'll either be a pointless no-op or throw aBadMethodCallException.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I wasn't hinting at implementing it everywhere, but decoupling the traversal of the form tree from the actual form field clearing.

Like the visitor pattern, if you will.
But this edge case doesn't seem too severe.

colinodell reacted with thumbs up emoji
@nicolas-grekasnicolas-grekas added this to thenext milestoneJun 14, 2018
*
* @return $this
*/
publicfunctionclearErrors($deep =false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Let's add type hint to argumentpublic function clearErrors(bool $deep = false);.
But please don't add: self, we already had discussion on this (#27190 (comment)).

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Added and amended! Thanks for the feedback 👍

vudaltsov reacted with thumbs up emoji
@colinodellcolinodellforce-pushed thefeature/clearable-forms branch 2 times, most recently fromf365b92 tof86e407CompareJune 14, 2018 23:47
@vudaltsov
Copy link
Contributor

If the method isclearErrors than probably the interface might beClearableErrorsInterface?

@colinodellcolinodellforce-pushed thefeature/clearable-forms branch fromf86e407 to17c427eCompareJune 14, 2018 23:55
@colinodell
Copy link
ContributorAuthor

Good idea@vudaltsov, I like that better! I have made that change.

Copy link
Contributor

@vudaltsovvudaltsov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Awesome! Looking forward to AJAX partial form reloading without errors workarounds 😃

Copy link
Contributor

@HeahDudeHeahDude left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Looks good, thanks!

*
* @return $this
*/
publicfunctionclearErrors(bool$deep =false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

You should type hint: self here

Copy link
Contributor

@vudaltsovvudaltsovJun 16, 2018
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@HeahDude , we had a discussion on return types here:#27190 (comment)
The problem will be that when using->clearErrors()-> on actual object implementing this interface, the IDE will not show any other methods in autocomplete, because: self is not: static. So from my opinion it's much better to leave@return $this phpdoc.

Copy link
Contributor

@jvasseurjvasseurJun 16, 2018
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

You can leave the@return $this phpdoc and add: self at the same time. AFAIK phpdoc takes precedence with type declaration for IDE auto completion, this means we would get both the correct auto completion and strictness at the language level (that an instance of the interface is returned).

Copy link
Contributor

@vudaltsovvudaltsovJun 16, 2018
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

okay, then let's use: self 😄

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Using: self on an interface forces theForm subclass implementation to use a: ClearableErrorsInterace typehint:

image

Fatal error: Declaration of Symfony\Component\Form\Form::clearErrors(bool $deep = false): Symfony\Component\Form\Form must be compatible with Symfony\Component\Form\ClearableErrorsInterface::clearErrors(bool $deep = false): Symfony\Component\Form\ClearableErrorsInterface in src/Symfony/Component/Form/Form.php on line 61

I'm not sure this is what we want.

AFAIK phpdoc takes precedence with type declaration for IDE auto completion

I could not get this working in the latest version of PhpStorm:

image

Furthermore, I could not find any other interfaces in Symfony with a: self return type hint. For these reasons I think we should leave it as-is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The fact that we don't have any existing interfaces with aself return type hint is probably because we couldn't make use of them before Symfony 4. So I would still use it here and use the docblock to be more precise.

/**
* Removes all the errors of this form.
*
* @param bool $deep whether to remove errors from child forms as well
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Symfony code base uses capital style to comment params.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Fixed, amended, and force-pushed :) Thanks for catching that!

/**
* {@inheritdoc}
*/
publicfunctionclearErrors(bool$deep =false)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

missing return type hint (same in the interface)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

actually I am not even sure if it makes sense that this method returns anything

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

All form methods are chainable, so it makes sense to keep it here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

colinodell reacted with thumbs up emoji
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think it's time to decide this once and for all inhttps://symfony.com/doc/current/contributing/code/standards.html

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Well, fluent methods are a pain for return types. so even if we want to have as much return types as possible for new APIs, I'm not sure we want them for fluent APIs.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@xabbuh@stof I have removedreturn $this; from the method for a few reasons:

  1. You're right, this method doesn't really need to be chainable.
  2. ClearableTokenStorageInterface (a new and similar interface introduced in SF4) does not return anything, so perhaps we should be consistent here.
  3. It seems like there's no definitive rule on how to type hint interface methods that return$this /self. I don't want to set a bad precedent here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Then you should add: void in interface and class

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

But I am for consistency withFormInterface which has@return $this on methods likeaddError. Although I agree that fluent interfaces are pain.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I've changed my mind and addedreturn $this; back in. I could see developers wanting to call$form->clearErrors()->createView() so this definitely has value.

The last unanswered question is what to do about return types. Our ultimate goal is to haveForm::clearErrors() return that originalForm instance. Here's what theReturn Type Declarations RFC has to say about our current situation:

The enforcement of the declared return type during inheritance is invariant; this means that when a sub-type overrides a parent method then the return type of the child must exactly match the parent and may not be omitted.

This is why using: self on the interface requires theForm method to use: ClearableErrorsInterface which is not ideal.

However, the RFC goes on to say:

If the parent does not declare a return type then the child is allowed to declare one.

Because this is a valid approach, I thinkomitting the return type from the interface but using: self on theForm makes the most sense in this situation:

  1. A return type on the interface is pointless because there are literally no other methods onClearableErrorsInterface. Is somebody really going to call$form->clearErrors()->clearErrors()->clearErrors()?
  2. This gives us the functionality we want (accurate return type hint onForm) despite PHP's current limitations with invariant return types.

xabbuh reacted with thumbs up emoji
*
* @return $this
*/
publicfunctionclearErrors(bool$deep =false):self
Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@xabbuh I have added a: self return type here per your request. See#27580 (comment) for an explanation of why I didn't also add a return type to the interface. Let me know your thoughts :)

@colinodell
Copy link
ContributorAuthor

Tests are failing, but I don't think it's because of my changes. All tests undersrc/Symfony/Component/Form are passing locally.

@fabpotfabpotforce-pushed thefeature/clearable-forms branch fromed74efd to9eb755cCompareJune 25, 2018 09:51
@fabpot
Copy link
Member

Thank you@colinodell.

@fabpotfabpot merged commit9eb755c intosymfony:masterJun 25, 2018
fabpot added a commit that referenced this pull requestJun 25, 2018
This PR was squashed before being merged into the 4.2-dev branch (closes#27580).Discussion----------[Form] Add ability to clear form errors| Q             | A| ------------- | ---| Branch?       | master| Bug fix?      | no| New feature?  | yes| BC breaks?    | no| Deprecations? | no| Tests pass?   | yes| Fixed tickets |#14060| License       | MIT| Doc PR        |symfony/symfony-docs#9916This PR adds the ability to manually clear form errors, thus improving the DX issue reported in#14060.Unlike my original approach in#14233 and#27571 which break BC, this adds a new `ClearableErrorInterface` which `Form` implements.  (`Button` does not implement it because buttons can't have errors.)Commits-------9eb755c [Form] Add ability to clear form errors
@fabpot
Copy link
Member

Changelog added ina1eb649 (forgot to comment before merging)

javiereguiluz added a commit to symfony/symfony-docs that referenced this pull requestJun 25, 2018
…uiluz)This PR was merged into the master branch.Discussion----------[Form] Ability to clear form errorsDocumenting the new feature proposed insymfony/symfony#27580Commits-------f07f536 Wrap long lines and add the versionadded directive7a4465d Clarify that clearing errors makes the form validd4143f1 [Form] Ability to clear form errors
@nicolas-grekasnicolas-grekas modified the milestones:next,4.2Nov 1, 2018
This was referencedNov 3, 2018
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@stofstofstof left review comments

@ycerutoycerutoyceruto left review comments

@fabpotfabpotfabpot approved these changes

@nicolas-grekasnicolas-grekasnicolas-grekas approved these changes

@xabbuhxabbuhxabbuh approved these changes

+5 more reviewers

@jvasseurjvasseurjvasseur left review comments

@apfelboxapfelboxapfelbox left review comments

@vudaltsovvudaltsovvudaltsov approved these changes

@HeahDudeHeahDudeHeahDude approved these changes

@maxheliasmaxheliasmaxhelias approved these changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Projects

None yet

Milestone

4.2

Development

Successfully merging this pull request may close these issues.

13 participants

@colinodell@TerjeBr@vudaltsov@fabpot@nicolas-grekas@stof@jvasseur@apfelbox@xabbuh@yceruto@HeahDude@maxhelias@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp