diff --git a/src/Controller/Api/v1/StopsController.php b/src/Controller/Api/v1/StopsController.php index 69caaf3..76c19a1 100644 --- a/src/Controller/Api/v1/StopsController.php +++ b/src/Controller/Api/v1/StopsController.php @@ -14,6 +14,7 @@ use Nelmio\ApiDocBundle\Annotation\Model; use Swagger\Annotations as SWG; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; +use Tightenco\Collect\Support\Collection; /** * Class StopsController @@ -51,7 +52,7 @@ class StopsController extends Controller break; default: - $result = $stops->getAllGroups(); + $result = $stops->getAll(); } return $this->json($result->all()); @@ -77,14 +78,14 @@ class StopsController extends Controller { switch (true) { case $request->query->has('name'): - $result = $stops->findGroupsByName($request->query->get('name')); + $result = $stops->findByName($request->query->get('name')); break; default: - $result = $stops->getAllGroups(); + $result = $stops->getAll(); } - return $this->json($result->all()); + return $this->json(static::group($result)->all()); } /** @@ -130,4 +131,18 @@ class StopsController extends Controller return array_combine(['track', 'order'], $tuple); })); } -} \ No newline at end of file + + public static function group(Collection $stops) + { + return $stops->groupBy(function (Stop $stop) { + return $stop->getGroup(); + })->map(function ($stops, $key) { + $group = new StopGroup(); + + $group->setName($key); + $group->setStops($stops); + + return $group; + })->values(); + } +} diff --git a/src/Entity/StopEntity.php b/src/Entity/StopEntity.php index 20f8176..1978a41 100644 --- a/src/Entity/StopEntity.php +++ b/src/Entity/StopEntity.php @@ -9,7 +9,9 @@ use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(readOnly=true) - * @ORM\Table("stop") + * @ORM\Table("stop", indexes={ + * @ORM\Index(name="group_idx", columns={"group_name"}) + * }) */ class StopEntity implements Entity, Fillable { @@ -27,10 +29,18 @@ class StopEntity implements Entity, Fillable * Stop name * @var string * - * @ORM\Column(type="string") + * @ORM\Column(type="string", length=255) */ private $name; + /** + * Stop group name + * @var string|null + * + * @ORM\Column(type="string", length=255, nullable=true, name="group_name") + */ + private $group; + /** * Optional stop description, should not be longer than 255 chars * @var string|null @@ -43,7 +53,7 @@ class StopEntity implements Entity, Fillable * Optional stop variant - for example number of shed * @var string|null * - * @ORM\Column(type="string", nullable=true) + * @ORM\Column(type="string", length=255, nullable=true) */ private $variant; @@ -81,6 +91,16 @@ class StopEntity implements Entity, Fillable $this->name = $name; } + public function getGroup(): ?string + { + return $this->group; + } + + public function setGroup(?string $group): void + { + $this->group = $group; + } + public function getDescription(): ?string { return $this->description; @@ -130,4 +150,4 @@ class StopEntity implements Entity, Fillable { $this->onDemand = $onDemand; } -} \ No newline at end of file +} diff --git a/src/Migrations/Version20200131151757.php b/src/Migrations/Version20200131151757.php new file mode 100644 index 0000000..5e12a9c --- /dev/null +++ b/src/Migrations/Version20200131151757.php @@ -0,0 +1,45 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'sqlite', 'Migration can only be executed safely on \'sqlite\'.'); + + $this->addSql('CREATE TEMPORARY TABLE __temp__stop AS SELECT id, provider_id, name, description, variant, latitude, longitude, on_demand FROM stop'); + $this->addSql('DROP TABLE stop'); + $this->addSql('CREATE TABLE stop (id VARCHAR(255) NOT NULL COLLATE BINARY, provider_id VARCHAR(255) DEFAULT NULL COLLATE BINARY, name VARCHAR(255) NOT NULL COLLATE BINARY, description VARCHAR(255) DEFAULT NULL COLLATE BINARY, variant VARCHAR(255) DEFAULT NULL COLLATE BINARY, latitude DOUBLE PRECISION DEFAULT NULL, longitude DOUBLE PRECISION DEFAULT NULL, on_demand BOOLEAN NOT NULL, group_name VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('INSERT INTO stop (id, provider_id, name, description, variant, latitude, longitude, on_demand) SELECT id, provider_id, name, description, variant, latitude, longitude, on_demand FROM __temp__stop'); + $this->addSql('DROP TABLE __temp__stop'); + $this->addSql('CREATE INDEX group_idx ON stop (group_name)'); + } + + public function down(Schema $schema) : void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'sqlite', 'Migration can only be executed safely on \'sqlite\'.'); + + $this->addSql('DROP INDEX group_idx'); + $this->addSql('CREATE TEMPORARY TABLE __temp__stop AS SELECT id, name, description, variant, latitude, longitude, on_demand, provider_id FROM stop'); + $this->addSql('DROP TABLE stop'); + $this->addSql('CREATE TABLE stop (id VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description VARCHAR(255) DEFAULT NULL, variant VARCHAR(255) DEFAULT NULL, latitude DOUBLE PRECISION DEFAULT NULL, longitude DOUBLE PRECISION DEFAULT NULL, on_demand BOOLEAN NOT NULL, provider_id VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))'); + $this->addSql('INSERT INTO stop (id, name, description, variant, latitude, longitude, on_demand, provider_id) SELECT id, name, description, variant, latitude, longitude, on_demand, provider_id FROM __temp__stop'); + $this->addSql('DROP TABLE __temp__stop'); + } +} diff --git a/src/Model/Stop.php b/src/Model/Stop.php index 123c60d..87eeefa 100644 --- a/src/Model/Stop.php +++ b/src/Model/Stop.php @@ -57,6 +57,15 @@ class Stop implements Referable, Fillable */ private $onDemand = false; + /** + * Name of group that this stop is part of. + * + * @Serializer\Type("string") + * @SWG\Property(example="Jasień PKM") + * @var string|null + */ + private $group; + public function getName(): string { return $this->name; @@ -106,4 +115,14 @@ class Stop implements Referable, Fillable { $this->location = $location; } + + public function getGroup(): ?string + { + return $this->group; + } + + public function setGroup(?string $group): void + { + $this->group = $group; + } } diff --git a/src/Provider/Database/GenericStopRepository.php b/src/Provider/Database/GenericStopRepository.php index d3e4279..df092f9 100644 --- a/src/Provider/Database/GenericStopRepository.php +++ b/src/Provider/Database/GenericStopRepository.php @@ -4,7 +4,6 @@ namespace App\Provider\Database; use App\Entity\StopEntity; use App\Model\Stop; -use App\Model\StopGroup; use App\Provider\StopRepository; use Tightenco\Collect\Support\Collection; use Kadet\Functional as f; @@ -18,11 +17,6 @@ class GenericStopRepository extends DatabaseRepository implements StopRepository return collect($stops)->map(f\ref([$this, 'convert'])); } - public function getAllGroups(): Collection - { - return $this->group($this->getAll()); - } - public function getById($id): ?Stop { $id = $this->id->generate($this->provider, $id); @@ -34,12 +28,12 @@ class GenericStopRepository extends DatabaseRepository implements StopRepository public function getManyById($ids): Collection { $ids = collect($ids)->map(f\apply(f\ref([$this->id, 'generate']), $this->provider)); - $stops = $this->em->getRepository(StopEntity::class)->findBy(['id' => $ids->all()]); + return collect($stops)->map(f\ref([$this, 'convert'])); } - public function findGroupsByName(string $name): Collection + public function findByName(string $name): Collection { $query = $this->em->createQueryBuilder() ->select('s') @@ -47,22 +41,6 @@ class GenericStopRepository extends DatabaseRepository implements StopRepository ->where('s.name LIKE :name') ->getQuery(); - $stops = collect($query->execute([':name' => "%$name%"]))->map(f\ref([$this, 'convert'])); - - return $this->group($stops); - } - - private function group(Collection $stops) - { - return $stops->groupBy(function (Stop $stop) { - return $stop->getName(); - })->map(function ($stops, $key) { - $group = new StopGroup(); - - $group->setName($key); - $group->setStops($stops); - - return $group; - })->values(); + return collect($query->execute([':name' => "%$name%"]))->map(f\ref([$this, 'convert'])); } } diff --git a/src/Provider/Dummy/DummyStopRepository.php b/src/Provider/Dummy/DummyStopRepository.php index cdb8ecb..caea318 100644 --- a/src/Provider/Dummy/DummyStopRepository.php +++ b/src/Provider/Dummy/DummyStopRepository.php @@ -27,11 +27,6 @@ class DummyStopRepository implements StopRepository return collect(); } - public function getAllGroups(): Collection - { - return collect(); - } - public function getById($id): ?Stop { return Stop::createFromArray(['id' => $id, 'name' => 'lorem']); @@ -42,8 +37,8 @@ class DummyStopRepository implements StopRepository return collect($ids)->map(f\ref([ $this, 'getById' ])); } - public function findGroupsByName(string $name): Collection + public function findByName(string $name): Collection { return collect(); } -} \ No newline at end of file +} diff --git a/src/Provider/StopRepository.php b/src/Provider/StopRepository.php index 1b8e700..ea87c03 100644 --- a/src/Provider/StopRepository.php +++ b/src/Provider/StopRepository.php @@ -10,10 +10,7 @@ use Tightenco\Collect\Support\Collection; interface StopRepository extends Repository { public function getAll(): Collection; - public function getAllGroups(): Collection; - public function getById($id): ?Stop; public function getManyById($ids): Collection; - - public function findGroupsByName(string $name): Collection; -} \ No newline at end of file + public function findByName(string $name): Collection; +} diff --git a/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php b/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php index 0606fe7..abf6553 100644 --- a/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php +++ b/src/Provider/ZtmGdansk/ZtmGdanskDataUpdateSubscriber.php @@ -162,14 +162,17 @@ class ZtmGdanskDataUpdateSubscriber implements EventSubscriberInterface && $stop['depot'] !== 1; }) ->map(function ($stop) use ($provider) { + $name = trim($stop['stopName'] ?? $stop['stopDesc']); + return StopEntity::createFromArray([ 'id' => $this->ids->generate($provider, $stop['stopId']), - 'name' => trim($stop['stopName'] ?? $stop['stopDesc']), - 'variant' => trim($stop['zoneName'] == 'Gdańsk' ? $stop['stopCode'] : null), + 'name' => $name, + 'variant' => trim($stop['zoneName'] == 'Gdańsk' ? $stop['stopCode'] ?? $stop['subName'] : null), 'latitude' => $stop['stopLat'], 'longitude' => $stop['stopLon'], 'onDemand' => (bool)$stop['onDemand'], 'provider' => $provider, + 'group' => $name, ]); }) ; diff --git a/src/Service/EntityConverter.php b/src/Service/EntityConverter.php index 0ed9f68..222a7c8 100644 --- a/src/Service/EntityConverter.php +++ b/src/Service/EntityConverter.php @@ -86,6 +86,7 @@ final class EntityConverter implements Converter, RecursiveConverter 'name' => $entity->getName(), 'variant' => $entity->getVariant(), 'description' => $entity->getDescription(), + 'group' => $entity->getGroup(), 'location' => new Location( $entity->getLongitude(), $entity->getLatitude()