doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.93k stars 2.52k forks source link

Problem in prod mode - MappingException #10595

Closed maouache closed 1 year ago

maouache commented 1 year ago

Bug Report

Hello, I had a weird problem, I created a symfony 6.2.7 project with the doctrine version here is the info:

Composer.json file:

"doctrine/doctrine-bundle": "^2.7",
"doctrine/doctrine-fixtures-bundle": "^3.4",
"doctrine/doctrine-migrations-bundle": "^3.2",
"doctrine/orm": "^2.13",

I created my Person entity with php bin/console make:entity which generated Personne.php (class Personne) and in doctrine table personne of course with the migration and all the steps.

When I wanted to switch to prod mode: I got this error message:


{ "message": "Uncaught PHP Exception Doctrine\Persistence\Mapping\MappingException: \"Class 'App\Entity\personne' does not exist" at /home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException. php line 80", "context":{"exception":{"class": "Doctrine\Persistence\MappingException", "message": "Class 'App\Entity\personne' does not exist", "code":0, "file":"/home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/MappingException. php:80"}},"level":500,"level_name":"CRITICAL","channel":"request","datetime":"2023-03-24T15:29:59.022378+01:00","extra":{}}

It looks like doctrine is looking for a class called 'App\\Entity\\personne' when it's actually 'App\\Entity\\Personne'.

Temporary solution

For the moment I diverted that with a duplication of the file Personne.php and personne.php so that it works in both prod and dev mode. of in dev mode you don't need the duplication file.

Used but not working

I tried all the cache option delete:

php bin/console doctrine:cache:clear-metadata --env=prod 
php bin/console cache:warmup --env=prod --no-debug
php bin/console doctrine:mapping:info --env=prod
php bin/console cache:clear --env=prod

The links of symfony for the deployment here they are all: https://symfony.com/doc/current/deployment.html. https://symfony.com/doc/3.4/setup/file_permissions.html https://github.com/sonata-project/SonataAdminBundle/issues/5021

Where the error comes from ?

I think the problem comes from doctrine which converts 'Personne' into 'personne' when doctrine is in prod mode, so it triggers MappingException with the message "App\Entity' does not exist" because there is not file called personne.php but Personne.php exist.

greg0ire commented 1 year ago

I don't know why Doctrine would do this. Things I would do if I were you:

maouache commented 1 year ago

Composer Outdated

 patch or minor release available - update recommended
- major release available - update possible
doctrine/instantiator         1.5.0   2.0.0   A small, lightweight utility to instantiate objects in ...
doctrine/lexer                2.1.0   3.0.0   PHP Doctrine Lexer parser library that can be used in T...
sensio/framework-extra-bundle v6.2.10 v6.2.10 This bundle provides a way to configure your controller...
Package sensio/framework-extra-bundle is abandoned, you should avoid using it. Use Symfony instead.

Stack Trace il give you my last prod.log

{"message":"Matched route \"app_site\".","context":{"route":"app_site","route_parameters":{"_route":"app_site","_controller":"App\\Controller\\SiteController::index"},"request_uri":"https://127.0.0.1:8000/sites","method":"GET"},"level":200,"level_name":"INFO","channel":"request","datetime":"2023-03-24T15:29:59.013327+01:00","extra":{}}
{"message":"Checking for authenticator support.","context":{"firewall_name":"main","authenticators":0},"level":100,"level_name":"DEBUG","channel":"security","datetime":"2023-03-24T15:29:59.014226+01:00","extra":{}}
{"message":"Uncaught PHP Exception Doctrine\\Persistence\\Mapping\\MappingException: \"Class 'App\\Entity\\personne' does not exist\" at /home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php line 80","context":{"exception":{"class":"Doctrine\\Persistence\\Mapping\\MappingException","message":"Class 'App\\Entity\\personne' does not exist","code":0,"file":"/home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php:80"}},"level":500,"level_name":"CRITICAL","channel":"request","datetime":"2023-03-24T15:29:59.022378+01:00","extra":{}}
{"message":"Matched route \"app_site\".","context":{"route":"app_site","route_parameters":{"_route":"app_site","_controller":"App\\Controller\\SiteController::index"},"request_uri":"https://127.0.0.1:8000/sites","method":"GET"},"level":200,"level_name":"INFO","channel":"request","datetime":"2023-03-24T16:13:19.760728+01:00","extra":{}}
{"message":"Checking for authenticator support.","context":{"firewall_name":"main","authenticators":0},"level":100,"level_name":"DEBUG","channel":"security","datetime":"2023-03-24T16:13:19.761422+01:00","extra":{}}
{"message":"Uncaught PHP Exception Doctrine\\Persistence\\Mapping\\MappingException: \"Class 'App\\Entity\\personne' does not exist\" at /home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php line 80","context":{"exception":{"class":"Doctrine\\Persistence\\Mapping\\MappingException","message":"Class 'App\\Entity\\personne' does not exist","code":0,"file":"/home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php:80"}},"level":500,"level_name":"CRITICAL","channel":"request","datetime":"2023-03-24T16:13:19.764672+01:00","extra":{}}

Use a debugger based on what I see in the stack trace

How can i use a debugger in prod because he show me directly 500 error message, can you give me more information ? do you mean prod in with debug = true ?

greg0ire commented 1 year ago

Stack Trace il give you my last prod.log

That's not a stack trace.

Use XDebug with a breakpoint, in dev, in prod mode.

mpdude commented 1 year ago

Do a case-sensitive search with you IDE for personne, maybe you wrote it that way somewhere?

maouache commented 1 year ago

Before using the xdebug and doing what you asked me to do we'll do it step by step:

To explain you well what happens: I have these routes:

-/
-/dashboard/
-/person/
-/site/
'APP_ENV' => 'dev' && 'APP_DEBUG' => '1':
-/           ===> OK
-/dashboard/ ===> OK
-/personne/  ===> OK
-/site/      ===> OK
'APP_ENV' => 'dev' && 'APP_DEBUG' => '0':
-/              ===> OK
-/dashboard/    ===> ERROR: The server returned a "500 Internal Server Error". request.CRITICAL: Uncaught PHP Exception Doctrine\Persistence\Mapping\MappingException: "Class 'App\Entity\personne' does not exist" at /home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php line 80 {"exception":"[object] (Doctrine\\Persistence\\Mapping\\MappingException(code: 0): Class 'App\\Entity\\personne' does not exist at /home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php:80)"} []
-/personne/     ===> same ERROR
-/site/         ===> Same ERROR

Capture d’écran du 2023-03-27 11-16-37

'APP_ENV' => 'prod' && 'APP_DEBUG' => '1':
-/              ===> OK
-/dashboard/    ===> OK
-/personne/     ===> OK
-/site/         ===> OK
'APP_ENV' => 'prod' && 'APP_DEBUG' => '0':

-/              ===> OK
-/dashboard/    ===> ERROR: The server returned a "500 Internal Server Error". request.CRITICAL: Uncaught PHP Exception Doctrine\Persistence\Mapping\MappingException: "Class 'App\Entity\personne' does not exist" at /home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php line 80 {"exception":"[object] (Doctrine\\Persistence\\Mapping\\MappingException(code: 0): Class 'App\\Entity\\personne' does not exist at /home/mohamed/Workspace/Symfony/cnfm/project/geco/vendor/doctrine/persistence/src/Persistence/Mapping/MappingException.php:80)"} []
-/personne/     ===> OK
-/site/         ===> Same ERROR

I notice that when the debug is activated it finds all the controllers, as well as the routes, but without the debug active I have this error

I need help how I can upgrade these packages with the command "compose outdated":

- patch or minor release available - update recommended
- major release available - update possible
doctrine/instantiator 1.5.0 2.0.0 A small, lightweight utility to instantiate objects in PHP without ...
doctrine/lexer        2.1.0 3.0.0 PHP Doctrine Lexer parser library that can be used in Top-Down, Rec...

I have tried composing update and composing upgrade I can't get them up to date.

greg0ire commented 1 year ago

It's composer, not composing, that's why it doesn't work :trollface: But you don't need to update those (and might not even be able to in the case of doctrine/lexer).

Now that's cleared up, I'm a bit surprised at the design of the error page… In Symfony, there used to be a stack trace tab, as shown here: https://symfony.com/doc/current/contributing/code/stack_trace.html#getting-stack-traces-with-symfony

maouache commented 1 year ago

sorry i mean composer update or upgrade not updating doctrine/instantiator and doctrine/lexer. yeah me too it's new design for symfony 6.2.7, i didn't find Stack Traces when i got the error in ('APP_ENV' => 'dev' && 'APP_DEBUG' => '0')

raphael-geffroy commented 1 year ago

With APP_DEBUG at false you won't see a stacktrace I don't think it's design related. Are you using sonata or any genericity between controllers and entities ?

maouache commented 1 year ago

I don't know what sonata is, but I made it simple with symfony, here is my code:

Created by php/bin console make:entity + doctrine:migration + doctrine:migrate

Personne.php

<?php

namespace App\Entity;

use App\Repository\PersonneRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: PersonneRepository::class)]
class Personne
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne(inversedBy: 'personnes', targetEntity: Adresse::class)]
    private ?adresse $adresse = null;

    #[ORM\ManyToOne(inversedBy: 'personnes', targetEntity: Site::class)]
    private ?site $site = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $titre = null;

    #[ORM\Column(length: 255)]
    private ?string $nom = null;

    #[ORM\Column(length: 255)]
    private ?string $prenom = null;

    #[ORM\Column(length: 255, nullable: true)]
    private ?string $email = null;

    #[ORM\Column(length: 127, nullable: true)]
    private ?string $telephone = null;

    #[ORM\Column(length: 127, nullable: true)]
    private ?string $fax = null;

    #[ORM\Column(type: Types::SMALLINT)]
    private ?int $valide = null;

    #[ORM\OneToMany(mappedBy: 'responsable', targetEntity: Logiciel::class)]
    private Collection $logiciels;

    #[ORM\OneToMany(mappedBy: 'responsable', targetEntity: Pole::class)]
    private Collection $poles;

    #[ORM\OneToMany(mappedBy: 'responsablePedagogique', targetEntity: Installation::class)]
    private Collection $installationsPedagogique;

    #[ORM\OneToMany(mappedBy: 'responsableTechnique', targetEntity: Installation::class)]
    private Collection $installationsTechnique;

    #[ORM\OneToMany(mappedBy: 'responsableSite', targetEntity: Site::class)]
    private Collection $responsableSites;

    #[ORM\OneToMany(mappedBy: 'responsableFinancier', targetEntity: Site::class)]
    private Collection $responsableFinancierSites;

    #[ORM\OneToMany(mappedBy: 'responsableContractuel', targetEntity: Site::class)]
    private Collection $responsableContractuelSites;

    #[ORM\OneToMany(mappedBy: 'personne', targetEntity: Compte::class)]
    private Collection $comptes;

    #[ORM\ManyToMany(targetEntity: Convention::class, mappedBy: 'personnes')]
    private Collection $conventions;

    public function __construct()
    {
        $this->logiciels = new ArrayCollection();
        $this->poles = new ArrayCollection();
        $this->installationsPedagogique = new ArrayCollection();
        $this->installationsTechnique = new ArrayCollection();
        $this->responsableSites = new ArrayCollection();
        $this->responsableFinancierSites = new ArrayCollection();
        $this->responsableContractuelSites = new ArrayCollection();
        $this->comptes = new ArrayCollection();
        $this->conventions = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getAdresse(): ?adresse
    {
        return $this->adresse;
    }

    public function setAdresse(?adresse $adresse): self
    {
        $this->adresse = $adresse;

        return $this;
    }

    public function getSite(): ?site
    {
        return $this->site;
    }

    public function setSite(?site $site): self
    {
        $this->site = $site;

        return $this;
    }

    public function getTitre(): ?string
    {
        return $this->titre;
    }

    public function setTitre(?string $titre): self
    {
        $this->titre = $titre;

        return $this;
    }

    public function getNom(): ?string
    {
        return $this->nom;
    }

    public function setNom(string $nom): self
    {
        $this->nom = $nom;

        return $this;
    }

    public function getPrenom(): ?string
    {
        return $this->prenom;
    }

    public function setPrenom(string $prenom): self
    {
        $this->prenom = $prenom;

        return $this;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(?string $email): self
    {
        $this->email = $email;

        return $this;
    }

    public function getTelephone(): ?string
    {
        return $this->telephone;
    }

    public function setTelephone(?string $telephone): self
    {
        $this->telephone = $telephone;

        return $this;
    }

    public function getFax(): ?string
    {
        return $this->fax;
    }

    public function setFax(?string $fax): self
    {
        $this->fax = $fax;

        return $this;
    }

    public function getValide(): ?int
    {
        return $this->valide;
    }

    public function setValide(int $valide): self
    {
        $this->valide = $valide;

        return $this;
    }

    /**
     * @return Collection<int, Logiciel>
     */
    public function getLogiciels(): Collection
    {
        return $this->logiciels;
    }

    public function addLogiciel(Logiciel $logiciel): self
    {
        if (!$this->logiciels->contains($logiciel)) {
            $this->logiciels->add($logiciel);
            $logiciel->setResponsable($this);
        }

        return $this;
    }

    public function removeLogiciel(Logiciel $logiciel): self
    {
        if ($this->logiciels->removeElement($logiciel)) {
            // set the owning side to null (unless already changed)
            if ($logiciel->getResponsable() === $this) {
                $logiciel->setResponsable(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Pole>
     */
    public function getPoles(): Collection
    {
        return $this->poles;
    }

    public function addPole(Pole $pole): self
    {
        if (!$this->poles->contains($pole)) {
            $this->poles->add($pole);
            $pole->setResponsable($this);
        }

        return $this;
    }

    public function removePole(Pole $pole): self
    {
        if ($this->poles->removeElement($pole)) {
            // set the owning side to null (unless already changed)
            if ($pole->getResponsable() === $this) {
                $pole->setResponsable(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Installation>
     */
    public function getInstallationsPedagogique(): Collection
    {
        return $this->installationsPedagogique;
    }

    public function addInstallationPedagogique(Installation $installation): self
    {
        if (!$this->installationsPedagogique->contains($installation)) {
            $this->installationsPedagogique->add($installation);
            $installation->setResponsablePedagogique($this);
        }

        return $this;
    }

    public function removeInstallationPedagogique(Installation $installation): self
    {
        if ($this->installationsPedagogique->removeElement($installation)) {
            // set the owning side to null (unless already changed)
            if ($installation->getResponsablePedagogique() === $this) {
                $installation->setResponsablePedagogique(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Installation>
     */
    public function getInstallationsTechnique(): Collection
    {
        return $this->installationsTechnique;
    }

    public function addInstallationTechnique(Installation $installation): self
    {
        if (!$this->installationsTechnique->contains($installation)) {
            $this->installationsTechnique->add($installation);
            $installation->setResponsablePedagogique($this);
        }

        return $this;
    }

    public function removeInstallationTechnique(Installation $installation): self
    {
        if ($this->installationsTechnique->removeElement($installation)) {
            // set the owning side to null (unless already changed)
            if ($installation->getResponsablePedagogique() === $this) {
                $installation->setResponsablePedagogique(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Site>
     */
    public function getResponsableSites(): Collection
    {
        return $this->responsableSites;
    }

    public function addResponsableSite(Site $site): self
    {
        if (!$this->responsableSites->contains($site)) {
            $this->responsableSites->add($site);
            $site->setResponsableSite($this);
        }

        return $this;
    }

    public function removeResponsableSite(Site $site): self
    {
        if ($this->responsableSites->removeElement($site)) {
            // set the owning side to null (unless already changed)
            if ($site->getResponsableSite() === $this) {
                $site->setResponsableSite(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Site>
     */
    public function getResponsableFinancierSites(): Collection
    {
        return $this->responsableFinancierSites;
    }

    public function addResponsableFinancierSite(Site $site): self
    {
        if (!$this->responsableFinancierSites->contains($site)) {
            $this->responsableFinancierSites->add($site);
            $site->setResponsableFinancier($this);
        }

        return $this;
    }

    public function removeResponsabFinancierleSite(Site $site): self
    {
        if ($this->responsableFinancierSites->removeElement($site)) {
            // set the owning side to null (unless already changed)
            if ($site->getResponsableFinancier() === $this) {
                $site->setResponsableFinancier(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Site>
     */
    public function getResponsableContractuelSites(): Collection
    {
        return $this->responsableContractuelSites;
    }

    public function addResponsableContractuelSite(Site $site): self
    {
        if (!$this->responsableContractuelSites->contains($site)) {
            $this->responsableContractuelSites->add($site);
            $site->setResponsableContractuel($this);
        }

        return $this;
    }

    public function removeResponsabContractuelSite(Site $site): self
    {
        if ($this->responsableContractuelSites->removeElement($site)) {
            // set the owning side to null (unless already changed)
            if ($site->getResponsableContractuel() === $this) {
                $site->setResponsableContractuel(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Compte>
     */
    public function getComptes(): Collection
    {
        return $this->comptes;
    }

    public function addCompte(Compte $compte): self
    {
        if (!$this->comptes->contains($compte)) {
            $this->comptes->add($compte);
            $compte->setPersonne($this);
        }

        return $this;
    }

    public function removeCompte(Compte $compte): self
    {
        if ($this->comptes->removeElement($compte)) {
            // set the owning side to null (unless already changed)
            if ($compte->getPersonne() === $this) {
                $compte->setPersonne(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection<int, Convention>
     */
    public function getConventions(): Collection
    {
        return $this->conventions;
    }

    public function addConvention(Convention $convention): self
    {
        if (!$this->conventions->contains($convention)) {
            $this->conventions->add($convention);
            $convention->addPersonne($this);
        }

        return $this;
    }

    public function removeConvention(Convention $convention): self
    {
        if ($this->conventions->removeElement($convention)) {
            $convention->removePersonne($this);
        }

        return $this;
    }

    public function verifierLiens(): ?string
    {
        $lienResponableSite = $this->getResponsableSites()->count();
        $lienResponableFinancierSite = $this->getResponsableFinancierSites()->count();
        $lienResponableContractuelSite = $this->getResponsableContractuelSites()->count();
        $lienResponableSite = $this->getResponsableSites()->count();
        $lienPole = $this->getPoles()->count();
        $lienInstallations = $this->getInstallationsTechnique()->count() + $this->getInstallationsPedagogique()->count();
        $lienCompte = $this->getComptes()->count();

        $message = "Suppression Impossible !<br>";
        $result = "";

        if ($lienResponableSite > 0 || $lienResponableFinancierSite > 0 || $lienResponableContractuelSite > 0) {
            $countSite = $lienResponableSite + $lienResponableFinancierSite + $lienResponableContractuelSite;
            $result .= "Lien(s) avec " . $countSite . " site(s)<br>";
        }

        if ($lienPole > 0) {
            $result .= "Lien(s) avec " . $lienPole . " pole(s)<br>";
        }

        if ($lienInstallations > 0) {
            $result .= "Lien(s) avec " . $lienInstallations . " installation(s)<br>";
        }

        if ($lienCompte > 0) {
            $result .= "Lien(s) avec " . $lienCompte . " compte(s)<br>";
        }

        if ($result == "")
            return $result;

        return $message . $result;
    }

    public function __toString(): string
    {
        return $this->titre . " " . $this->nom;
    }
}

PersonneController.php

<?php

namespace App\Controller;

use App\Form\AdresseType;
use App\Form\PersonneType;
use App\Repository\PersonneRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class PersonneController extends AbstractController
{
    /*

    =======les tâches qui reste à faire et à relier avec d'autres modules:=======
    -->symfony UX pour le champs site:
        builder->add(champs site avec l'autocomplete);
    -->sécurité des sessions:
        $security->isGranted('ROLE_ADMIN')
    -->ajouter ces actions dans l'historique:
        $historique->addElement($this->getUser(), 'Consulter', 'personne');
        $historique->addElement($utilisateur, 'Ajouter', 'Personne '.$personne->getNom().' '.$personne->getPrenom());
    */

    #[Route('/personnes', name: 'app_personne')]
    public function index(PersonneRepository $personneRepository): Response
    {
        $personnesQuery = $personneRepository->findAll();

        $personnes = [];

        foreach ($personnesQuery as $personne) {
            $personnes[] = [
                'id' => $personne->getId(),
                'titre' => $personne->getTitre(),
                'nom' => $personne->getNom(),
                'prenom' => $personne->getPrenom(),
                'email' => $personne->getEmail(),
                'telephone' => $personne->getTelephone(),
                'fax' => $personne->getFax(),
                'adresse' => $personne->getAdresse() ? $personne->getAdresse()->__toString() : "",
                'site' => $personne->getSite() ? $personne->getSite()->getNom() : ""
            ];
        }

        return $this->render('personne/index.html.twig', [
            'controller_name' => 'PersonneController',
            'personnes' => $personnes
        ]);
    }

    #[Route('/personnes/ajouter', name: 'app_personne_new')]
    public function new(FormFactoryInterface $factory, Request $request, EntityManagerInterface $em): Response
    {
        $builder = $factory->createBuilder(PersonneType::class);

        $form = $builder->add('Adresse', AdresseType::class)
            ->getForm();

        $form->handleRequest($request);

        $formView = $form->createView();

        if ($form->isSubmitted() && $form->isValid()) {
            $personne = $form->getData();

            $personne->setValide(1);
            $adresse = $personne->getAdresse();

            $em->persist($adresse);
            $em->persist($personne);
            $em->flush();

            $this->addFlash('success', 'Ajout effectuée');

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

        return $this->render('personne/new.html.twig', [
            'controller_name' => 'PersonneController',
            'formView' => $formView
        ]);
    }

    #[Route('/personnes/{id}', name: 'app_personne_show')]
    public function show($id, PersonneRepository $personneRepository): Response
    {
        $personne = $personneRepository->find($id);

        return $this->render('personne/show.html.twig', [
            'controller_name' => 'PersonneController',
            'personne' => $personne
        ]);
    }

    #[Route('/personnes/edit/{id}', name: 'app_personne_edit')]
    public function edit($id, PersonneRepository $personneRepository, Request $request, EntityManagerInterface $em): Response
    {
        $personne = $personneRepository->find($id);

        $form = $this->createForm(PersonneType::class, $personne);

        $form->add('Adresse', AdresseType::class);

        $form->handleRequest($request);

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

            $em->persist($personne->getAdresse());
            $em->persist($personne);

            $em->flush();

            $this->addFlash('success', 'Les données de la personne ont été modifié avec succès !');

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

        $formView = $form->createView();

        return $this->render('personne/edit.html.twig', [
            'controller_name' => 'PersonneController',
            'formView' => $formView
        ]);
    }

    #[Route('/personnes/delete/{id}', name: 'app_personne_delete')]
    public function delete($id, PersonneRepository $personneRepository, EntityManagerInterface $em): Response
    {
        $personne = $personneRepository->find($id);

        $adresse = $personne->getAdresse();

        $message = $personne->verifierLiens();

        if ($message != "") {
            $this->addFlash('errors', $message);
        } else {
            $em->remove($personne);
            $em->remove($adresse);
            $em->flush();

            $this->addFlash('success', 'La suppression a été effectué avec succès !');
        }

        return $this->redirectToRoute('app_personne');
    }
}
raphael-geffroy commented 1 year ago

Can you open a repository on github so I can have a look and try to replicate ?

maouache commented 1 year ago

No I can't. I asked my superior to fix the problem you asked me to open a repository on github, so that you help me to fix the problem, he refused, it's a company project they want to keep private. for the moment the duplication of the file Personne.php (with personne.php in lower case) it's enough for him.