Symfony Form: unsetAllFieldsExcept()
When creating forms in symfony which extends from a Base (ORM) class, you sometimes do not need all fields that Propel/Doctrine generates for you. If you want to remove them you have several ways to do so.
1. Unset the fiels you don’t need.
public function configure() {
unset($this['field1'], $this['field2'], ... );
}
Simple way to remove the fields you don’t want, but if you change something in your database, which has an impact on that form (new column, foreignkey, etc ), it will be added in the (generated) super class. And if you don’t update the unset function with that extra field, it will be expected in the form. Unless you have unit tests for all your forms this could brake it without knowing it.
2. Override the setup function.
/**
* @override
*/
public function setup()
{
parent::setup();
$this->setWidgets(...);
$this->setValidators(...);
}
Another way is to override the setup function and do your own widgets and validators initialization. This is a good way to only intialize the fields you really need, but you’ll have to do what your ORM generated for you.
3. Use a function which unsets all fields except the one you need (like the enableAllPluginsExcept function).
$this->unsetAllFieldsExcept(array(
'field1',
'field2',
'field3',
...));
This would be usefull, because it will remove all fields you do not want to use, and even if new fields are added it will not use them. The drawback is that if you have 20 fields and only need to unset one of them, you’ll have more type work
.
Since it does not exist in symfony, I quickly created our own function. This function should be added in the class BaseFormPropel.class:
abstract class BaseFormPropel extends sfFormPropel
{
public function setup() {
}
protected function unsetAllFieldsExcept($fields = array()) {
$unsetFields = array_diff(array_keys($this->getWidgetSchema()->getFields()), $fields);
foreach($unsetFields as $value) {
unset($this[$value]);
}
}
}
Which one to use ?
None of them are better. But if you need to reset a majority of the fields the ORM has generated then I would go for the method 2. If you only need to unset the fields you do not want to use then I would use the function unsetAllFieldsExcept().
Which method do/would you use ?

I’d go for the second one (unsetAllFieldsExcept()). I might even need this myself soon to clean up some of my forms
What I don’t like about this though is that it is very inefficient from a performance point of view. It just seems wrong to me to create a form with 20+ widgets and validators just to kill 19 of them immediately. Perhaps I should think about this a little more…
Correct for the performance issue.
If in the form you create you need to unset/reinitialize at least one field then it’s better to override the setup function and initialize it from the first time correctly.
The problem is that those (important) things are not well documented in symfony (yet), and some developers do not take the time to ‘investigate’ what happens in the super classes.
I saw a lot of form examples where the developers “re-set” there widgets/validators in the configure method instead of the setup function. The configure method, which is correctly named, is only to configure the existing widgets/validators (options etc).
If I have the time I’ll do some benchmarking on the ‘unsetting’ fields to see how much performance drop there is.
This is more a security problem. If you add new fields in your model, then fields will appear on the form. Not always what we need.
I have coded a similar function with a optional parameter to reorder field.
http://trac.symfony-project.org/browser/plugins/swToolboxPlugin/sf1.2/trunk/lib/form/swToolboxFormHelper.class.php#L270
Today I discovered that symfony 1.3 will include an sfForm::useFields() method that will do exactly what your unsetAllFieldsExcept() does:
http://trac.symfony-project.org/changeset/17824
That’s good news