'Symfony 5 - Get old collection data before submit form

In my symfony 5 project I would like when submitting a certain form, compare the entity before and after submission.

So keep a copy of the original entity in order to perform processing.

I've :

$parametresAdmin = $entrepriseService->getParametresAdmin();

        $form = $this->createForm(ParametresAdminType::class, $parametresAdmin, [
            'entreprise' => $this->getUser()->getEntreprise(),
        ]);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $entrepriseService->updateParametres($parametresAdmin);

             return $this->redirectToRoute('admin_parametres');
        }

In fact, I want to get a copie of $parametresAdmin->getTypesConges() (which is a collection on OneToMany).

So, when the form is submitted, I want compare the old $parametresAdmin->getTypesConges() and the new $parametresAdmin->getTypesConges().

The "$parametresAdmin->getTypesConges()" part looks like this:

enter image description here

I can add / modify leave types on the fly. Except that I do not want to authorize the possibility of modifying the "Balance type" field for the types of leave that already exist. There is just for those that I add that I leave the possibility in the ChoiceType. So on the front side, it's good. But on the back side, no.

But it doesn't work

What I do :

I change the "Solde initial" for the first line : enter image description here

But when I submit, I've the same value (the new value : 10 )

enter image description here

EDIT : Currently, I've now :

        $parametresAdmin = $entrepriseService->getParametresAdmin();
        $typeConges = $parametresAdmin->getTypesConges();
        $oldTypesConges = clone $typeConges;

        $form = $this->createForm(ParametresAdminType::class, $parametresAdmin, [
            'entreprise' => $this->getUser()->getEntreprise(),
        ]);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $typeConges = $parametresAdmin->getTypesConges(); // update with new data
            dd($oldTypesConges, $parametresAdmin->getTypesConges());

            $entrepriseService->updateParametres($parametresAdmin);

            return $this->redirectToRoute('admin_parametres');
        }


Solution 1:[1]

You should clone your data like this :

$typeConges = $parametresAdmin->getTypesConges();
$oldTypeConges = clone $typeConges;
// handleRequest(), isValid(), isSubmit() ...
$typeConges = $parametresAdmin->getTypesConges(); // update with new data
dd(oldTypeConges, $parametresAdmin->getTypesConges());

phpdoc says about :

When an object is cloned, PHP will perform a shallow copy of all of the object's properties. Any properties that are references to other variables will remain references.

Take a look at this question on stackoverflow.

Solution 2:[2]

Use session variables to store the old data:

To store your data before rendering the form in the controller, use:

$this->get('session')->set('oldTypesConges ', $typesConges );

And after submitting, read the data stored to compare it with the new one:

$oldTypesConges = $this->get('session')->get('oldTypesConges ');

Now, you can compare $typesConges and $oldTypesConges.

This solution was inspired from here: How to set session variables for all the controllers in Symfony2?

Solution 3:[3]

$versionsBeforeSubmit = [];
foreach($produit->getVersions()->getIterator() as $version) {
    $versionsBeforeSubmit[] = clone $version;
}
$form->handleRequest($request);


if($form->isValid() && !$hasError) {
    dump($versionsBeforeSubmit);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Hamid ER-REMLI
Solution 3