Décrivez ici votre problème ou ce que vous cherchez à faire.

Hello (encore une fois),

Je suis sur un petit projet Symfony/ApiPlatform mais je dois avouer que je bloque vraiment sur un (petit ?) problème..

J'ai plusieurs entités dont une entité @Ville, une entité @Entreprise et une entité @Responsable.
Chaque ville peut avoir plusieurs entreprises, et chaque entreprise peut avoir plusieurs villes ;
Chaque entreprise peut avoir plusieurs responsables, mais chaque responsable ne peut avoir qu'une seule entreprise.

Donc un responsable doit être lié à une entreprise mais aussi à une ville. Par exemple :

L'entreprise Tuto SAS est présente sur Nantes et Nice, nous avons un responsable pour Nantes et un autre responsable pour Nice.
Jusqu'à présent, c'est très simple. Mais là où les choses se compliquent, c'est que je n'arrive pas à limiter un responsable uniquement aux villes de l'entreprise.
Par exemple le responsable de Nantes de l'entreprise Tuto SAS, ne doit pas pouvoir changer sa ville pour Bordeaux, étant donné que son entreprise n'est pas présente dans cette ville.

J'essaye de le faire depuis mon évenements en PRE_VALIDATE, j'arrive à récupérer l'entreprise du responsable mais par contre la méthode $entreprise->getVille() me retourne mon objet @Entreprise plutôt que l'objet ville ?

class ResponsableVilleSubscriber implements EventSubscriberInterface
{

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::VIEW => ['setVilleForResponsable', EventPriorities::PRE_VALIDATE]
        ];
    }

    public function setVilleForResponsable(ViewEvent $event)
    {
        $result = $event->getControllerResult();
        $method = $event->getRequest()->getMethod();
        if ($result instanceof Responsable && ($method === "POST" || $method === "PATCH"))
        {
            $entreprise = $result->getEntreprise();
            $ville = $result->getVille();
            $entrepriseVille = $entreprise->getVille();
            if($ville instanceof Ville){
                dd(
                    $entreprise, // dd : retourne mon objet entreprise
                    $ville,     // dd : retourne la ville que l'utilisateur souhaite
                    $fleetCity  // dd : retourne aussi mon objet entreprise ?
                );
            } else {
                dd("Ceci n'est pas une instance de @Ville ; else");
            }
        };
    }
}

Ce que je veux

C'est assez simple, à ce stade l'utilisateur peut s'attribuer la ville qu'il souhaite, comme la ville de Bordeaux (à condition de connaître son IRI), même si son entreprise n'est pas présente dans cette ville mais que sur Nantes et Nice. J'aimerais donc limiter la possibilité uniquement aux mêmes villes que son entreprise.
Un responsable d'une même entreprise peut changer de ville, tant qu'il respecte une des villes de son entreprise.
J'essaye donc de récupérer son entreprise, la ville qu'il souhaite s'attribuer mais aussi les villes de son entreprise pour pouvoir faire une condition :

if($villeSouhaité == $villeDeMonEntreprise) { alors j'assigne la ville; } else { je retourne une erreur : Vous n'avez pas accès à cette ville; }

Ce que j'obtiens

Je n'arrive pas à faire la condition ci-dessus car il m'est impossible de récupérer les villes de l'entreprise du responsable. Pourtant, j'arrive bien à obtenir l'entreprise du responsable, la ville qu'il souhaite s'attribuer mais ma méthode $entreprise->getVille() me retourne mon objet entreprise :

dd($entrepriseVille); =

ResponsableVilleSubscriber.php on line 35:
Doctrine\ORM\PersistentCollection {#1049
  #collection: Doctrine\Common\Collections\ArrayCollection {#1051
    -elements: []
  }
  #initialized: false
  -snapshot: []
  -owner: Proxies\__CG__\App\Entity\Fleet {#797
    -id: 3
    -createdAt: DateTimeImmutable @1662842908 {#1052
      date: 2022-09-10 20:48:28.0 UTC (+00:00)
    }
    -entreprise: "Tuto SAS"
    -entrepriseStatus: "SAS"
    -city: Doctrine\ORM\PersistentCollection {#1049}
    -Responsables: Doctrine\ORM\PersistentCollection {#1056
      #collection: Doctrine\Common\Collections\ArrayCollection {#1057
        -elements: []
      }
      #initialized: false
      -snapshot: []
      -owner: Proxies\__CG__\App\Entity\Fleet {#797 …2}
      -association: array:15 [ …15]
      -em: Doctrine\ORM\EntityManager {#642 …11}
      -backRefFieldName: "fleet"
      -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#692 …}
      -isDirty: false
    }
    -Clients: Doctrine\ORM\PersistentCollection {#1058
      #collection: Doctrine\Common\Collections\ArrayCollection {#1059
        -elements: []
      }
      #initialized: false
      -snapshot: []
      -owner: Proxies\__CG__\App\Entity\Fleet {#797 …2}
      -association: array:15 [ …15]
      -em: Doctrine\ORM\EntityManager {#642 …11}
      -backRefFieldName: "fleet"
      -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#796 …}
      -isDirty: false
    }
    +__isInitialized__: true
     …2
  }
  -association: array:20 [ …20]
  -em: Doctrine\ORM\EntityManager {#642 …11}
  -backRefFieldName: "fleets"
  -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#770 …}
  -isDirty: false
}

(PS: J'ai modifié mes variables en FR pour une meilleure compréhension de mon problème)

1 réponse


Re,

J'ai "trouver" la solution à mon problème, néanmoins j'ignore si c'est la bonne méthode à suivre. Si quelqu'un à une meilleure idée pour un code plus propre, c'est avec grand plaisir :

public function setVilleForResponsable(ViewEvent $event)
    {
        $result = $event->getControllerResult();
        $method = $event->getRequest()->getMethod();
        if ($result instanceof Responsable && ($method === "POST" || $method === "PATCH"))
        {
            $entreprise = $result->getEntreprise();
            $ville = $result->getVille();
            if($ville instanceof Ville && in_array($ville, $entreprise->getVille()->toArray()){
                    $result->setVille($ville);
            } else {
                die();
            }
        };
    }