symfony1
symfony1 copied to clipboard
SaveEmbeddedForms replaced by saveObjectEmbeddedForms ???
Hi,
We have a project with Symfony 1.4 which worked. After replacing Symfony with this version, found that the subform functionality was not working as expected.
Turns out the original symfony form function SaveEmbeddedForms has been removed and saveObjectEmbeddedForms is being called instead.
Also noticed, the validators in subforms while being called, are not able to modify the values. We provided a "Remove" button in subform list, and in validator where checking for the remove flag, and removing that item from the values. This no longer works, despite removing the item, at the saveObjectEmbeddedForms, if we do a $form->getValues($subform_name), we get the originally submitted values, not the values modified by the validator.
Try this version instead https://github.com/punkave/symfony1
Hey! I think that I have the same problem! Any solution to apply in LExpress fork?
IMO, this is the wrong way to remove a subform from a list, you must do that before submitting the form.
Can you explain how to remove a subform before the user has requested the removal ? You mentioning the remove before form submit is basically asking the same I think. How does the code know in advance which subform the user has asked to remove ?
If you are saying that before "bind" we should do that, then it basically means the same as I suggested "bind" / "saveEmbeddedForms" of the parent.
You need to do it before calling the bind
method.
You can use something like that, in your form class:
public function bind(array $taintedValues = null, array $taintedFiles = null)
{
// get actual sub forms
$subForms = array_keys($this->embeddedForms);
// get submitted parameters
$subParams = null !== $taintedValues ? array_keys($taintedValues) : array();
// add new forms
foreach (array_diff($subParams, $subForms) as $index)
{
if (strval($index) === self::$CSRFFieldName)
{
continue;
}
$subForm = new sfForm(); // build your new form here
$this->embedForm($index, $subForm);
$this->widgetSchema->setLabel($index, 'added subform'); // configure the label here
}
// unset deleted line forms
foreach (array_diff($subForms, $subParams) as $index)
{
unset($this[$index]);
}
parent::bind($taintedValues, $taintedFiles);
}
This is the power of our hacked embedded form implementation.
Thank you for that. Always good to know about other methods.
SaveEmbeddedForms will still be involved though, in order to remove the values from the database. This can not be done at the bind stage as validation error will (and should) stop delete action. And subforms database addition / removal only should proceed after parent form save.
You can manage addition/deletion of item into your doctrine (for example) collection in the overwritted bind
method. Call on save will be done after, and as your collection had already been altered object will be add or delete from your database on doctrine form save.
Solved?
First, this breaks existing code, so this version of symfony can not be used with existing projects where you simply wish to add PHP 5.5 / 5.6 compatibility.
We also found that if there is a post validator which removes an item from taintedvalues, those values re-appear rendering the validator useless.