Skip to content

Commit

Permalink
feature: added rank field and updated query action
Browse files Browse the repository at this point in the history
Added a new rank field to the airport entity
Updated Query action to order by rank
  • Loading branch information
amvid committed May 14, 2024
1 parent 73ba7ab commit 4a9d41c
Show file tree
Hide file tree
Showing 22 changed files with 145 additions and 47 deletions.
17 changes: 14 additions & 3 deletions .docker/php/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
#!/usr/bin/env sh

composer install
if [ ! -d "vendor" ]; then
echo "Vendor directory not found. Installing dependencies..."
composer install
else
echo "Vendor directory found. Skipping dependency installation."
fi

bin/console assets:install

vendor/bin/rr get-binary -f v2024.1.1 --location bin
chmod +x bin/rr
if [ ! -f "bin/rr" ]; then
echo "RoadRunner binary not found. Downloading..."
vendor/bin/rr get-binary -f v2024.1.1 --location bin
chmod +x bin/rr
else
echo "RoadRunner binary found. Skipping download."
fi

bin/rr serve -c .rr.dev.yaml
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ up:
dev:
@docker compose up

.PHONY: coldstart
coldstart:
-rm -rf vendor
-rm -rf bin/rr
@docker compose up

.PHONY: install
install:
@docker compose up -d
Expand Down
31 changes: 31 additions & 0 deletions migrations/Version20240514101332.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240514101332 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE airport ADD rank DOUBLE PRECISION NOT NULL');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE airport DROP rank');
}
}
1 change: 1 addition & 0 deletions src/Airport/Action/Create/CreateAirportAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public function run(CreateAirportActionRequest $request): CreateAirportActionRes
$airport = $this->airportFactory
->setIata($request->iata)
->setIcao($request->icao)
->setRank($request->rank)
->setTitle($request->title)
->setLatitude($request->latitude)
->setLongitude($request->longitude)
Expand Down
2 changes: 2 additions & 0 deletions src/Airport/Action/Create/CreateAirportActionRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,6 @@ class CreateAirportActionRequest
#[NotBlank]
#[Length(max: 150)]
public string $timezone;

public float $rank = 0.0;
}
57 changes: 25 additions & 32 deletions src/Airport/Action/Query/QueryAirportsAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ public function __construct(
) {
}

/**
* @throws TimezoneNotFoundException
* @throws CityNotFoundException
*/
public function run(QueryAirportsActionRequest $request): QueryAirportsActionResponse
{
/** @var array<Airport> $airports */
Expand All @@ -36,48 +32,45 @@ public function run(QueryAirportsActionRequest $request): QueryAirportsActionRes
foreach ($airports as $airport) {
$city = $airport->getCity();
$country = $city->getCountry();
$map[$country->getTitle()][$city->getTitle()][] = $airport;
$cityIata = $city->getIata() ?? $airport->getIata();

if (!isset($map[$country->getTitle()])) {
$map[$country->getTitle()] = [];
}
if (!isset($map[$country->getTitle()][$cityIata])) {
$map[$country->getTitle()][$cityIata] = [];
}

$map[$country->getTitle()][$cityIata][] = $airport;
}

foreach ($map as $country => $cities) {
foreach ($cities as $city => $airports) {
foreach ($map as $countryTitle => $cities) {
foreach ($cities as $cityIata => $airports) {
$isGroup = count($airports) > 1;
$airport = $airports[0];

if ($isGroup) {
$ap = $airports[0];

foreach ($airports as $a) {
$cityEntity = $a->getCity();
$countryEntity = $cityEntity->getCountry();

if ($cityEntity === $countryEntity->getCapital()) {
$ap = $a;
break;
}
}

$cityTitle = $airports[0]->getCity()->getTitle();
$res[] = new QueryChildrenAirportResponse(
$city . ' (Any)',
$ap->getCity()->getIata() ?? $ap->getIata(),
$country,
$cityTitle . ' (Any)',
$cityIata,
$countryTitle
);
}

foreach ($airports as $airport) {
if (!$isGroup) {
$res[] = new QueryAirportResponse(
$parentIndex = count($res) - 1;

foreach ($airports as $airport) {
$res[$parentIndex]->children[] = new QueryAirportResponse(
$airport->getTitle(),
$airport->getIata(),
$country,
$countryTitle
);
continue;
}

$res[count($res) - 1]->children[] = new QueryAirportResponse(
} else {
$airport = $airports[0];
$res[] = new QueryAirportResponse(
$airport->getTitle(),
$airport->getIata(),
$country,
$countryTitle
);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/Airport/Action/Update/UpdateAirportAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ public function run(UpdateAirportActionRequest $request, UuidInterface $id): Upd
$this->airportFactory->setTimezone($timezone);
}

if ($request->rank) {
$this->airportFactory->setRank($request->rank);
}

if ($request->icao) {
$this->airportFactory->setIcao($request->icao);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Airport/Action/Update/UpdateAirportActionRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ class UpdateAirportActionRequest
public ?string $timezone = null;

public ?bool $isActive = null;

public ?float $rank = null;
}
12 changes: 6 additions & 6 deletions src/Airport/Command/Import/ImportAirports2FromJsonCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$exists = $this->airportRepository->findByIata($airport->Iata);

if ($exists) {
$exists->setRank($airport->Rank ?? 0.0);
$this->airportRepository->save($exists, true);

continue;
}

Expand Down Expand Up @@ -149,17 +152,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
->setTitle($airport->Name)
->setIcao($airport->Icao ?? null)
->setIata($airport->Iata)
->setRank($airport->Rank ?? 0.0)
->setLongitude((float)$airport->Longitude)
->setLatitude((float)$airport->Latitude)
->setAltitude((int)$airport->Elevation)
->create();

try {
$this->airportRepository->save($newAirport, true);
$imported++;
} catch (Throwable $e) {
dd($e->getMessage(), $airport);
}
$this->airportRepository->save($newAirport, true);
$imported++;

if ($imported % 2000 === 0) {
$this->em->clear();
Expand Down
7 changes: 4 additions & 3 deletions src/Airport/Controller/Admin/AirportCrudController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ public function configureFields(string $pageName): iterable

FormField::addFieldset('Basic'),
TextField::new('title')->setColumns(4),
TextField::new('iata')->setColumns(4),
TextField::new('icao')->setColumns(4),
BooleanField::new('isActive')->setColumns(4),
TextField::new('iata')->setColumns(2),
TextField::new('icao')->setColumns(2),
NumberField::new('rank')->setColumns(1),
BooleanField::new('isActive'),

FormField::addFieldset('Position'),
NumberField::new('longitude')->hideOnIndex()->setColumns(2),
Expand Down
2 changes: 2 additions & 0 deletions src/Airport/Controller/Response/AirportResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class AirportResponse
public string $title;
public string $iata;
public string $icao;
public float $rank;
public bool $isActive;
public float $longitude;
public float $latitude;
Expand All @@ -30,6 +31,7 @@ public function __construct(Airport $airport, bool $withRelations = true)
$this->title = $airport->getTitle();
$this->iata = $airport->getIata();
$this->icao = $airport->getIcao();
$this->rank = $airport->getRank();
$this->isActive = $airport->isActive();
$this->longitude = $airport->getLongitude();
$this->altitude = $airport->getAltitude();
Expand Down
15 changes: 15 additions & 0 deletions src/Airport/Entity/Airport.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ class Airport
#[ORM\Column(length: 150, unique: false, nullable: false)]
private string $title;

#[ORM\Column(nullable: false)]
private float $rank = 0;

#[ORM\Column(options: ['default' => true])]
private bool $isActive = true;

Expand All @@ -61,6 +64,18 @@ public function __toString(): string
return $this->title;
}

public function setRank(float $rank = 0.0): self
{
$this->rank = $rank;

return $this;
}

public function getRank(): float
{
return $this->rank;
}

public function isActive(): bool
{
return $this->isActive;
Expand Down
6 changes: 6 additions & 0 deletions src/Airport/Factory/AirportFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ public function setIcao(?string $icao = null): AirportFactoryInterface
return $this;
}

public function setRank(float $rank = 0.0): AirportFactoryInterface
{
$this->airport->setRank($rank);
return $this;
}

public function setIata(string $iata): AirportFactoryInterface
{
$this->airport->setIata($iata);
Expand Down
2 changes: 2 additions & 0 deletions src/Airport/Factory/AirportFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public function setAirport(Airport $airport): self;

public function setTitle(string $title): self;

public function setRank(float $rank = 0.0): self;

public function setIcao(?string $icao = null): self;

public function setIata(string $iata): self;
Expand Down
9 changes: 6 additions & 3 deletions src/Airport/Repository/AirportRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,22 @@ public function query(int $offset, int $limit, string $query): iterable
{
$params = new ArrayCollection();
$params->add(new Parameter('query', "$query%"));
$params->add(new Parameter('exactQuery', $query));
$params->add(new Parameter('isActive', true));

return $this->createQueryBuilder('a')
->setFirstResult($offset)
->setMaxResults($limit)
->join('a.city', 'c')
->join('c.country', 'co')
->where('a.title LIKE :query')
->orWhere('a.iata LIKE :query')
->orWhere('a.icao LIKE :query')
->where('a.iata LIKE :query')
->orWhere('a.title LIKE :query')
->orWhere('c.title LIKE :query')
->orWhere('co.title LIKE :query')
->andWhere('a.isActive = :isActive')
->orderBy('CASE WHEN a.iata = :exactQuery THEN 0 ELSE 1 END', 'ASC')
->addOrderBy('a.rank', 'DESC')
->addOrderBy('a.title', 'ASC')
->setParameters($params)
->getQuery()
->getResult();
Expand Down
2 changes: 2 additions & 0 deletions tests/Application/Airport/Api/V1/AirportControllerE2ETest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public function testCreateActionSuccess(): void
'longitude' => 11,
'latitude' => 22,
'altitude' => 10,
'rank' => 0.11,
];

$this->client->request(
Expand All @@ -56,6 +57,7 @@ public function testCreateActionSuccess(): void
self::assertResponseIsSuccessful();
self::assertResponseStatusCodeSame(Response::HTTP_OK);
self::assertEquals($content['title'], $response['title']);
self::assertEquals($content['rank'], $response['rank']);
}

public function testQueryActionSuccess(): void
Expand Down
4 changes: 4 additions & 0 deletions tests/Unit/Airport/Action/Create/CreateAirportActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class CreateAirportActionTest extends TestCase
private string $icao = 'TEST';
private string $title = 'Test Airport';
private string $cityTitle = CityDummy::TITLE;
private float $rank = 0.25;
private float $longitude = 11.11;
private float $latitude = 22.22;
private int $altitude = 33;
Expand All @@ -54,6 +55,7 @@ protected function setUp(): void
$this->request = new CreateAirportActionRequest();
$this->request->countryIso2 = $this->countryIso2;;
$this->request->timezone = $this->timezone;
$this->request->rank = $this->rank;
$this->request->iata = $this->iata;
$this->request->icao = $this->icao;
$this->request->title = $this->title;
Expand Down Expand Up @@ -245,6 +247,7 @@ public function testShouldReturnAValidResponse(): void
$this->factory->expects($this->once())->method('setTimezone')->with($timezone)->willReturn($this->factory);
$this->factory->expects($this->once())->method('setIata')->with($this->iata)->willReturn($this->factory);
$this->factory->expects($this->once())->method('setIcao')->with($this->icao)->willReturn($this->factory);
$this->factory->expects($this->once())->method('setRank')->with($this->rank)->willReturn($this->factory);
$this->factory->expects($this->once())->method('create')->with()->willReturn($airport);

$this->airportRepository
Expand All @@ -265,6 +268,7 @@ public function testShouldReturnAValidResponse(): void
$this->assertEquals($airport->getTitle(), $actual->airport->title);
$this->assertEquals($airport->getIata(), $actual->airport->iata);
$this->assertEquals($airport->getIcao(), $actual->airport->icao);
$this->assertEquals($airport->getRank(), $actual->airport->rank);
$this->assertEquals($airport->getLatitude(), $actual->airport->latitude);
$this->assertEquals($airport->getAltitude(), $actual->airport->altitude);
$this->assertEquals($airport->getLongitude(), $actual->airport->longitude);
Expand Down
Loading

0 comments on commit 4a9d41c

Please sign in to comment.