3

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');
        }
kiuega
  • 141
  • 1
  • 12
  • Assuming your currently posted code matches your actual code (it is easy to get confused when troubleshooting) then I suspect the problem is that $typeConges is actually an array. PHP performs a shallow clone which means that objects inside of the array are not cloned. So you might need to loop over $typeConges and clone each individual element. – Cerad Sep 25 '20 at 12:59

3 Answers3

3

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.

Lounis
  • 597
  • 7
  • 15
  • Yes, I tried like this too, but it still doesn't work. I've updated my first post by adding the current code. It's really weird – kiuega Sep 25 '20 at 08:46
  • Could you try `spl_object_hash($oldTypeConges)` and compare value with `spl_object_hash($parametresAdmin->getTypesConges())`, if it's same so it's not the solution and we have to find out why. – Lounis Sep 25 '20 at 09:16
  • I tried, and I've `0000000021b16e9700000000327f6e55` and `0000000021b16eb000000000327f6e55` so...no, it's not the same. I will update my first post to give more precisions on the goal of what I want if it can help you (first post updated with more context) – kiuega Sep 25 '20 at 09:26
  • I updated my first post again with exactly what I'm doing and the results of the dump. You can see that if I change the value of the "Initial Balance" from the 1st row to "10". When I validate, I see in the dump that the $ oldTypesConges still corresponds to the new value – kiuega Sep 25 '20 at 09:35
  • Yes i think this way `$oldTypesConges = clone $parametresAdmin->getTypesConges();`make a clone of method call unfortunately, so we need to create variable and clone it after. Take a loot at the updated post above. – Lounis Sep 25 '20 at 09:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222071/discussion-between-lounis-and-kiuega). – Lounis Sep 25 '20 at 09:41
  • Yes, I tried with your updated post, but same thing. I updated my first post with new current code – kiuega Sep 25 '20 at 09:42
0

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?

Hamid ER-REMLI
  • 200
  • 1
  • 7
0
$versionsBeforeSubmit = [];
foreach($produit->getVersions()->getIterator() as $version) {
    $versionsBeforeSubmit[] = clone $version;
}
$form->handleRequest($request);


if($form->isValid() && !$hasError) {
    dump($versionsBeforeSubmit);
}
Najd Mrabet
  • 163
  • 3
  • 17