From f3fc6cb071853806a02931892b2d1b22f97067c7 Mon Sep 17 00:00:00 2001 From: Kacper Donat Date: Tue, 4 Feb 2020 22:23:48 +0100 Subject: [PATCH] Add destination field in stops --- src/Entity/TrackEntity.php | 7 +++- src/Model/Stop.php | 23 +++++++++++++ src/Model/StopGroup.php | 4 +-- .../Database/GenericStopRepository.php | 33 ++++++++++++++++++- src/Service/SerializerContextFactory.php | 2 ++ 5 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/Entity/TrackEntity.php b/src/Entity/TrackEntity.php index 088d6c2..a56fd2e 100644 --- a/src/Entity/TrackEntity.php +++ b/src/Entity/TrackEntity.php @@ -44,7 +44,7 @@ class TrackEntity implements Entity, Fillable /** * Stops in track - * @var Collection + * @var StopInTrack[]|Collection * @ORM\OneToMany(targetEntity=StopInTrack::class, fetch="LAZY", mappedBy="track", cascade={"persist"}) * @ORM\OrderBy({"order": "ASC"}) */ @@ -104,4 +104,9 @@ class TrackEntity implements Entity, Fillable { $this->stopsInTrack = new ArrayCollection($stopsInTrack); } + + public function getFinal(): StopInTrack + { + return $this->getStopsInTrack()->last(); + } } diff --git a/src/Model/Stop.php b/src/Model/Stop.php index 87eeefa..a37764a 100644 --- a/src/Model/Stop.php +++ b/src/Model/Stop.php @@ -3,7 +3,9 @@ namespace App\Model; use JMS\Serializer\Annotation as Serializer; +use Nelmio\ApiDocBundle\Annotation\Model; use Swagger\Annotations as SWG; +use Tightenco\Collect\Support\Collection; /** * Class Stop @@ -66,6 +68,17 @@ class Stop implements Referable, Fillable */ private $group; + /** + * Collection of possible destination stops. + * + * @Serializer\Groups({"WithDestinations"}) + * @Serializer\Type("Collection") + * @SWG\Property(type="array", @SWG\Items(ref=@Model(type=Stop::class, groups={"Default"}))) + * + * @var Collection + */ + private $destinations; + public function getName(): string { return $this->name; @@ -125,4 +138,14 @@ class Stop implements Referable, Fillable { $this->group = $group; } + + public function getDestinations(): Collection + { + return $this->destinations; + } + + public function setDestinations(Collection $destinations): void + { + $this->destinations = $destinations; + } } diff --git a/src/Model/StopGroup.php b/src/Model/StopGroup.php index ad502bf..a2ef876 100644 --- a/src/Model/StopGroup.php +++ b/src/Model/StopGroup.php @@ -28,7 +28,7 @@ class StopGroup * @var Collection|Stop[] * @SWG\Property( * type="array", - * @SWG\Items(ref=@Model(type=Stop::class)) + * @SWG\Items(ref=@Model(type=Stop::class, groups={"Default", "WithDestinations"})) * ) */ private $stops; @@ -57,4 +57,4 @@ class StopGroup { return $this->stops; } -} \ No newline at end of file +} diff --git a/src/Provider/Database/GenericStopRepository.php b/src/Provider/Database/GenericStopRepository.php index df092f9..2d3aa9a 100644 --- a/src/Provider/Database/GenericStopRepository.php +++ b/src/Provider/Database/GenericStopRepository.php @@ -3,10 +3,14 @@ namespace App\Provider\Database; use App\Entity\StopEntity; +use App\Entity\StopInTrack; +use App\Entity\TrackEntity; use App\Model\Stop; +use App\Model\Track; use App\Provider\StopRepository; use Tightenco\Collect\Support\Collection; use Kadet\Functional as f; +use Kadet\Functional\Transforms as t; class GenericStopRepository extends DatabaseRepository implements StopRepository { @@ -41,6 +45,33 @@ class GenericStopRepository extends DatabaseRepository implements StopRepository ->where('s.name LIKE :name') ->getQuery(); - return collect($query->execute([':name' => "%$name%"]))->map(f\ref([$this, 'convert'])); + $stops = collect($query->execute([':name' => "%$name%"])); + + $destinations = collect($this->em->createQueryBuilder() + ->select('t', 'ts', 'ts2', 's') + ->from(TrackEntity::class, 't') + ->join('t.stopsInTrack', 'ts') + ->join('t.stopsInTrack', 'ts2') + ->join('ts2.stop', 's') + ->where('ts.stop IN (:stops)') + ->getQuery() + ->execute(['stops' => $stops->map(t\property('id'))->all()])) + ->reduce(function ($grouped, TrackEntity $track) { + foreach ($track->getStopsInTrack()->map(t\property('stop'))->map(t\property('id')) as $stop) { + $grouped[$stop] = ($grouped[$stop] ?? collect())->add($track); + } + + return $grouped; + }, collect()) + ->map(function (Collection $tracks) { + return $tracks->map(function (TrackEntity $track) { + return $this->convert($track->getFinal()->getStop()); + })->unique()->values(); + }) + ; + + return collect($stops)->map(f\ref([$this, 'convert']))->each(function (Stop $stop) use ($destinations) { + $stop->setDestinations($destinations[$this->id->generate($this->provider, $stop->getId())]); + }); } } diff --git a/src/Service/SerializerContextFactory.php b/src/Service/SerializerContextFactory.php index 9ce181f..94156b9 100644 --- a/src/Service/SerializerContextFactory.php +++ b/src/Service/SerializerContextFactory.php @@ -71,6 +71,8 @@ final class SerializerContextFactory foreach ($groups as $group) { if (array_key_exists($group, $annotation->map)) { $result[] = $annotation->map[$group]; + } else { + $result[] = $groups; } }