Skip to content

[2.3] [Form] Renamed option "virtual" to "inherit_data" and improved handling of such forms #6573

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

Merged
merged 3 commits into from
Apr 19, 2013

Conversation

webmozart
Copy link
Contributor

Bug fix: yes
Feature addition: yes
Backwards compatibility break: yes
Symfony2 tests pass: yes
Fixes the following tickets: #5899, #5720, #5578
Todo: -
License of the code: MIT
Documentation PR: symfony/symfony-docs#2107

This PR renames the option "virtual" to "inherit_data" for more clarity (the old option is deprecated and usable until 2.3). It also fixes the behavior of forms having that option set.

Forms with that option set will now correctly return their parents' data from getData(), getNormData() and getViewData(). Furthermore, getPropertyPath() was fixed for forms that inherit their parent data.

@vicb
Copy link
Contributor

vicb commented Jan 5, 2013

I think this PR should be split in 2:

  • The first PR would contain the second commit only (ie bug fix)
  • The second PR would contain the first commit (option name change)

What about considering $builder->include() as described in #5899 - this would be part of the second PR.

@webmozart
Copy link
Contributor Author

@vicb Splitting this PR up in two would greatly increase my workload for no particular benefit.

I don't like an include function. This would break BC (because modifying our interfaces) and at the same time be less flexible than inherit_data (since it cannot be defined in the form type that actually inherits its parent's data).

@vicb
Copy link
Contributor

vicb commented Jan 5, 2013

I see include() as an helper around add() that would also set the virtual/inherit_data option to true. So flexibility would be the same, usability better.

Breaking BC ??? Which do you expect to be more frequent, extending the FormBuilder or using the virtual option ?

@webmozart
Copy link
Contributor Author

I expect neither of them to be very frequent. IMO the most useful purpose of inherit_data is to create fieldset-like structures, which are only represented in the view, but not in the model. These structures would mostly be implemented as types, which need to be able to define the inherit_data option.

So I think passing inherit_data as option to add() is really an edge case that does not justify a dedicated helper. We don't have any other form option that features a dedicated helper in the interfaces.

@vicb
Copy link
Contributor

vicb commented Jan 5, 2013

So I think passing inherit_data as option to add() is really an edge case that does not justify a dedicated helper. We don't have any other form option that features a dedicated helper in the interfaces.

What I expect from a builder is to ease the construction of an object and I think include() is much more meaningful and intuitive than a virtual or inherit_data option and it would also allow auto-completion - but of course this is a personal opinion.

@webmozart
Copy link
Contributor Author

Postponed to 2.3.

@fabpot
Copy link
Member

fabpot commented Mar 6, 2013

As it's going to be merged in 2.3, the old behavior should be kept until 3.0.

@fabpot
Copy link
Member

fabpot commented Mar 23, 2013

I've just re-read the documentation before and after the change. Frankly, I don't think that the new name is much better than the old one. Considering that this will break BC at some point, I would like that we reconsider this change.

@Koc
Copy link
Contributor

Koc commented Mar 31, 2013

@bschussek two questions about this PR:

  1. Is now we can do not pass data_class option by hand (it will get it from parent form)?
  2. Is there possible do not add virtual field name to children fields full names? We are using virtual forms as nested containers and names got too long: i.e. guardclient[tabpanel][timline_tab][fieldset][task_notes] instead of guardclient[task_notes]

@Strate
Copy link
Contributor

Strate commented Apr 7, 2013

@bschussek will this PR fix #7570 ?

@shuogawa
Copy link

shuogawa commented Apr 7, 2013

Hi, I have created a code as below to create a form with little complicated layout.

class Question{
    protected $subject;
    protected $body;
}
class Answer{
    protected $subject;
    protected $body;
}
class FormData{
    protected $question;
    protected $answer;
}
class RowType extends AbstractType{
    public function setDefaultOptions($resolver){
        $resolver->setDefaults(array('virtual' => true));
    }
}
class QuestionAndAnswerType extends AbstractType{
    public function buildForm($builder, $options){
        $builder->add('row1', 'row');
        $builder->add('row2', 'row');
        $row1 = $builder->get('row1');
        $row2 = $builder->get('row2');
        $row1->add('question_subject', 'text', array('property_path'=>'question.subject'));
        $row1->add('answer_subject', 'text', array('property_path'=>'answer.subject'));
        $row2->add('question_body', 'textarea', array('property_path'=>'question.body'));
        $row2->add('answer_body', 'textarea', array('property_path'=>'answer.body'));
    }
}

With the code above, I have created the form with layered structure as below.

form
 row(virtual=true)
   text(property_path=question.subject)
   text(property_path=anwser.subject)
 row(virtual=true)
   textarea(property_path=question.body)
   textarea(property_path=anwser.body)

This form will show the below as a content as well as results.

<div class="row">
    <div class="span6">
        <input type="text">
    </div>
    <div class="span6">
        <input type="text">
    </div>
</div>
<div class="row">
    <div class="span6">
        <textarea></textarea>
    </div>
    <div class="span6">
        <textarea></textarea>
    </div>
</div>

However, this form returns an error as "Cannot write property "question_subject" to an array.".
I think this is due to an unclassified data_class in RowType. It is, however, not possible to specify the Data_Class.

The code above is an example and It would be necessary to have a hypothetical FormType which does not affect property_path to create a complicated form.

With that, I think the link below is a good sample
#6584

and #6573 is a necessary function.

Also, I would like to create a code as below which nested virtual formtype

form
  row(virtual=true)
    cell(virtual=true)
      text(property_path=firstName)
    text(property_path=lastName)
    cell(virtual=true)
    textarea(property_path=comment)

@webmozart
Copy link
Contributor Author

@shuogawa Did you test whether your form works with this PR applied?

@webmozart
Copy link
Contributor Author

@fabpot I still think that "inherit_data" is much better than "virtual", especially when you contrast the two options used for data mapping:

  • property_path: to read a field's data from a property of the parent's data
  • inherit_data: to inherit the parent's data

@fabpot
Copy link
Member

fabpot commented Apr 15, 2013

Even if the new name is better, I'm not sure the difference is enough to justify a BC break. What others think?

@Koc
Copy link
Contributor

Koc commented Apr 15, 2013

It is easy do s/virtual/inherit_data globally in project.

@fabpot
Copy link
Member

fabpot commented Apr 15, 2013

@Koc: What about bundles or Open-Source that want to support several Symfony versions?

@aderuwe
Copy link
Contributor

aderuwe commented Apr 16, 2013

virtual is good imo, it's a virtual field in my form - it will not be propagated to the data.

@webmozart
Copy link
Contributor Author

@fabpot They can use the old name. "virtual" will remain in as an alias until 3.0.

@webmozart
Copy link
Contributor Author

@aderuwe That's only part of the truth. The current naming (and documentation) suggested that virtual fields were somehow "skipped" by data mapping (which was the case). But truth is (after this PR) that they are not skipped. They just receive the same data as their parent.

@aderuwe
Copy link
Contributor

aderuwe commented Apr 16, 2013

@bschussek but the use-case (structuring the form differently to the underlying model) will still work? I ask because I really understood them as "skipped" and have used them as such. I guess I'll need to modify some stuff here and there. :)

That being said, virtual might not make sense for what you describe as it does somehow imply being "skipped".

@webmozart
Copy link
Contributor Author

@aderuwe You don't need to modify anything. The use cases of inherit_data are a superset of the use cases of virtual. That means, all use cases that worked with virtual will work with inherit_data, plus some more (see also the linked tickets).

@aderuwe
Copy link
Contributor

aderuwe commented Apr 16, 2013

@bschussek Ok, then I think I need to change my opinion on the name change, virtual implies skipped, inherit_data seems to cover more of the meat of it. And it's not a difficult BC to overcome.

@webmozart
Copy link
Contributor Author

Just to clarify again: Both virtual and inherit_data will work until 3.0, but virtual will be marked deprecated while inherit_data will be documented and promoted for the reason you just mentioned.

@fabpot
Copy link
Member

fabpot commented Apr 16, 2013

@bschussek Can you update this PR to take into account that virtual will be supported until 3.0?

@webmozart
Copy link
Contributor Author

Rebased and pushed.

fabpot added a commit that referenced this pull request Apr 19, 2013
This PR was merged into the master branch.

Discussion
----------

[2.3] [Form] Renamed option "virtual" to "inherit_data" and improved handling of such forms

Bug fix: yes
Feature addition: yes
Backwards compatibility break: yes
Symfony2 tests pass: yes
Fixes the following tickets: #5899, #5720, #5578
Todo: -
License of the code: MIT
Documentation PR: symfony/symfony-docs#2107

This PR renames the option "virtual" to "inherit_data" for more clarity (the old option is deprecated and usable until 2.3). It also fixes the behavior of forms having that option set.

Forms with that option set will now correctly return their parents' data from `getData()`, `getNormData()` and `getViewData()`. Furthermore, `getPropertyPath()` was fixed for forms that inherit their parent data.

Commits
-------

1290b80 [Form] Fixed the deprecation notes for the "virtual" option
ac2ca44 [Form] Moved parent data inheritance from data mappers to Form
8ea5e1a [Form] Renamed option "virtual" to "inherit_data"
@fabpot fabpot closed this Apr 19, 2013
@fabpot fabpot merged commit 1290b80 into symfony:master Apr 19, 2013
@Strate
Copy link
Contributor

Strate commented Jun 9, 2013

So, just updated to 2.3
Method setData still does not calls for virtual (inherit_data) form type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants