Home > Net >  Getter on a ManyToMany relation - Symfony\ApiPlatform
Getter on a ManyToMany relation - Symfony\ApiPlatform

Time:09-27

Describe here your problem or what you are trying to do.

Hello ,

I'm on a small Symfony/ApiPlatform project but I have to admit that I'm really stuck on a (small?) problem..

I have several entities including a @City entity, an @Company entity and an @Manager entity. Each city can have multiple companies, and each company can have multiple cities; Each company can have multiple managers, but each manager can only have one company.

So a manager must be linked to a company but also to a city. For instance :

MyCompany Limited is present in New York and Los Angeles, we have a manager for New York and another manager for Los Angeles. So far, it's very simple. But where things get tricky is that I can't limit a manager to only company cities. For example, the New York manager of MyCompagny Limited should not be able to change his city to Chicago, given that his company is not present in this city.

I try to do it from my events in PRE_VALIDATE, I manage to recover the manager's company but on the other hand the $company->getCity() method returns my @Company object rather than the city object?

class ManagerCitySubscriber implements EventSubscriberInterface
{

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

    public function setCityForManager(ViewEvent $event)
    {
        $result = $event->getControllerResult();
        $method = $event->getRequest()->getMethod();
        if ($result instanceof Manager && ($method === "POST" || $method === "PATCH"))
        {
            $company= $result->getCompany();
            $city= $result->getCity();
            $cityCompany = $company->getCity();
            if($city instanceof City){
                dd(
                    $company, // dd : return my company object
                    $city,     // dd : returns the city the user wants
                    $cityCompany // dd : return also my company object ?
                );
            } else {
                dd("This is not an instance of @City ; else");
            }
        };
    }
}

What I want

It's quite simple, at this stage the user (Manager) can assign himself the city he wants, such as the city of Chicago or Boston (provided he knows his IRI), even if his company is not present in this city but only in New York and Los Angeles. So I would like to limit the possibility only to the same cities as his company. A manager of the same company can change city, as long as he respects one of the cities of his company. So I'm trying to retrieve his company, the city he wants to assign himself but also the cities of his company to be able to make a condition:

if($desiredcity == $cityOfMyCompany) { then I assign the city; } else { I return an error: You don't have access to this city; }

what i get

I can't do the above condition because I can't retrieve the cities of the manager's company. However, I manage to get the manager's company, the city he wants to assign himself, but my $company->getCity() method returns my company object:

dd($cityCompany); =

ManagerCitySubscriber.php on line 35:
Doctrine\ORM\PersistentCollection {#1049
  #collection: Doctrine\Common\Collections\ArrayCollection {#1051
    -elements: []
  }
  #initialized: false
  -snapshot: []
  -owner: Proxies\__CG__\App\Entity\Company {#797
    -id: 3
    -createdAt: DateTimeImmutable @1662842908 {#1052
      date: 2022-09-10 20:48:28.0 UTC ( 00:00)
    }
    -company: "MyCompany Limited"
    -companyState: "Limited"
    -city: Doctrine\ORM\PersistentCollection {#1049}
    -Manager: Doctrine\ORM\PersistentCollection {#1056
      #collection: Doctrine\Common\Collections\ArrayCollection {#1057
        -elements: []
      }
      #initialized: false
      -snapshot: []
      -owner: Proxies\__CG__\App\Entity\Company {#797 …2}
      -association: array:15 [ …15]
      -em: Doctrine\ORM\EntityManager {#642 …11}
      -backRefFieldName: "company"
      -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\Company{#797 …2}
      -association: array:15 [ …15]
      -em: Doctrine\ORM\EntityManager {#642 …11}
      -backRefFieldName: "company"
      -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#796 …}
      -isDirty: false
    }
     __isInitialized__: true
     …2
  }
  -association: array:20 [ …20]
  -em: Doctrine\ORM\EntityManager {#642 …11}
  -backRefFieldName: "companies"
  -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#770 …}
  -isDirty: false
}

CodePudding user response:

Re,

I "found" the solution to my problem, however I don't know if this is the right method to follow. If anyone has a better idea for cleaner code, it's with great pleasure :

public function setCityForManager(ViewEvent $event)
    {
        $result = $event->getControllerResult();
        $method = $event->getRequest()->getMethod();
        if ($result instanceof Manager && ($method === "POST" || $method === "PATCH"))
        {
            $company= $result->getCompany();
            $city= $result->getCity();
            if($city instanceof City && in_array($city, $company->getCity()->toArray())) {
                $result->setCity($city);
            } else {
                die();
            }
        };
    }
  • Related