Compare commits

..

61 Commits

Author SHA1 Message Date
dredgy 7e3af37a46 Added achievement data 2026-04-29 18:22:49 +10:00
dredgy b94b1d8ec2 Added achievement data 2026-04-28 22:16:21 +10:00
dredgy 14aed7bf6e Added achievement data 2026-04-26 20:00:11 +10:00
dredgy f6d5b97784 Added achievement data 2026-04-26 15:16:17 +10:00
dredgy 1821b99524 Updated logo API 2026-04-26 12:45:01 +10:00
dredgy f8bac7f85a Updated logo API 2026-04-25 23:57:29 +10:00
dredgy 924e03334c Updated logo API 2026-04-25 23:49:08 +10:00
dredgy de183995b6 Updated logo API 2026-04-25 22:57:18 +10:00
dredgy 678096b463 Updated logo API 2026-04-23 21:32:25 +10:00
dredgy 110ed5b984 Updated logo API 2026-04-23 00:53:19 +10:00
dredgy bd8ef98d30 Added User API 2026-04-22 15:17:01 +10:00
dredgy d68e23e93a Added Crew and General Aviation Filters 2026-04-21 00:28:54 +10:00
dredgy 9e995eedef Added Crew and General Aviation Filters 2026-04-20 23:02:03 +10:00
dredgy a57775e141 Added Crew and General Aviation Filters 2026-04-20 22:30:34 +10:00
dredgy e007824fa9 Add more airlines and fix edit bugs 2026-04-20 16:42:11 +10:00
dredgy 061ee9dd07 Add more airlines and fix edit bugs 2026-04-20 13:48:15 +10:00
dredgy 5deefcbfb3 Add more airlines and fix edit bugs 2026-04-20 13:36:58 +10:00
dredgy 8d7d8f02d3 Add more airlines and fix edit bugs 2026-04-20 09:23:26 +10:00
dredgy 4244b8835d Add more airlines and fix edit bugs 2026-04-19 13:05:50 +10:00
dredgy d90f338321 Add more airlines and fix edit bugs 2026-04-18 16:45:13 +10:00
dredgy 63d6fb9e76 Add more airlines and fix edit bugs 2026-04-18 14:22:51 +10:00
dredgy 147bf43f09 Deduplicate airlines 2026-04-18 12:40:55 +10:00
dredgy 5066052013 Deduplicate airlines 2026-04-17 00:02:47 +10:00
dredgy a535521834 User can add/edit flights 2026-04-16 16:28:22 +10:00
dredgy 2a657bbbf7 User can add/edit flights 2026-04-14 20:52:38 +10:00
dredgy 4110b52ba5 User can add/edit flights 2026-04-14 20:06:33 +10:00
dredgy a9aa65f0d2 User can add/edit flights 2026-04-12 20:34:22 +10:00
dredgy 0f84ec023e Added Charts 2026-04-11 23:11:22 +10:00
dredgy f335951784 Added Charts 2026-04-11 23:00:35 +10:00
dredgy 95624f345c Added Charts 2026-04-11 20:49:01 +10:00
dredgy e83fd3bdca Added Charts 2026-04-11 17:30:16 +10:00
dredgy 7a07616f03 Corrected Korea 2026-04-09 11:20:16 +10:00
dredgy 43f5c8ac3e Started a flight view 2026-04-07 21:31:36 +10:00
dredgy 79469c02cf Started a flight view 2026-04-07 18:11:12 +10:00
dredgy 2ad8c65b86 Started a flight view 2026-04-06 11:49:54 +10:00
dredgy b53c92de36 Started a flight view 2026-04-06 11:13:35 +10:00
dredgy 968272754e Save user flights 2026-04-06 10:39:03 +10:00
dredgy 8da717a400 Save user flights 2026-04-05 21:38:36 +10:00
dredgy fcbf021af7 Save user flights 2026-04-05 18:55:39 +10:00
dredgy 9631e7949d Save user flights 2026-04-05 18:52:24 +10:00
dredgy d0fe6d78d3 Save user flights 2026-04-05 18:49:02 +10:00
dredgy b4e2caad07 Save user flights 2026-04-05 17:49:16 +10:00
dredgy e55c771318 Save user flights 2026-04-05 16:40:19 +10:00
dredgy 8a1581641b Save user flights 2026-04-05 15:06:27 +10:00
dredgy bf34c20d85 Added timezones 2026-04-05 12:38:59 +10:00
dredgy 509efbe821 Added timezones 2026-04-04 22:19:58 +10:00
dredgy 7f62c31456 Added timezones 2026-04-04 19:03:47 +10:00
dredgy 30b56ece8a Added timezones 2026-04-04 18:36:27 +10:00
dredgy 548e838e81 Added timezones 2026-04-04 18:21:01 +10:00
dredgy baff2066e6 Added timezones 2026-04-04 18:14:33 +10:00
dredgy 6bb6ff7f71 Added save functionality 2026-04-04 18:10:01 +10:00
dredgy 4ed4110ba0 Added search box 2026-04-04 12:01:07 +10:00
dredgy 236f075df4 Added search box 2026-04-04 09:55:53 +10:00
dredgy bfe246ab44 Added search box 2026-04-04 09:50:11 +10:00
dredgy 877caa3291 Added Imported Flights Table 2026-04-03 23:59:40 +10:00
dredgy 6a88d0cdfb Added Imported Flights Table 2026-04-03 18:34:07 +10:00
dredgy 063a393168 Converted to TS, add import 2026-04-03 18:14:42 +10:00
dredgy 89135a554a Added UpDb 2026-04-03 14:54:13 +10:00
dredgy 1d77ce140b Added UpDb 2026-04-03 14:53:07 +10:00
dredgy d7140f1554 Add airports 2026-04-03 14:28:17 +10:00
dredgy 8ec4e92541 Add airports 2026-04-03 14:16:16 +10:00
223 changed files with 18255 additions and 546 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
.env
vendor/
.git/
storage/app/private/images
storage/app/private
node_modules
public/hot
public/build
+8
View File
@@ -30,6 +30,14 @@ DB_DATABASE=flightsapi
DB_USERNAME=root
DB_PASSWORD=
PRODUCTION_DB_CONNECTION=
PRODUCTION_DB_HOST=
PRODUCTION_DB_PORT=
PRODUCTION_DB_DATABASE=
PRODUCTION_DB_USERNAME=
PRODUCTION_DB_PASSWORD=
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
@@ -0,0 +1,56 @@
<?php
namespace App\Console\Commands;
use App\Models\Airport;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
#[Signature('app:populate-airport-timezones')]
#[Description('Populate timezone data for all airports using lat/lng')]
class PopulateAirportTimezones extends Command
{
/**
* Execute the console command.
*/
public function handle()
{
Airport::whereNull('timezone')->chunkById(100, function ($airports) {
foreach ($airports as $airport) {
$zoneName = null;
$attempts = 0;
while ($zoneName === null && $attempts < 3) {
$response = Http::withoutVerifying()
->withOptions(['allow_redirects' => false])
->get('http://vip.timezonedb.com/v2.1/get-time-zone', [
'key' => config('app.timezone_api_key'),
'format' => 'json',
'by' => 'position',
'lat' => $airport->latitude_deg,
'lng' => $airport->longitude_deg,
]);
$zoneName = $response->json('zoneName');
$attempts++;
if ($zoneName === null) {
$this->warn("{$airport->name} — attempt {$attempts} failed: " . $response->body());
sleep(5);
}
}
if ($zoneName) {
$airport->update(['timezone' => $zoneName]);
$this->info("{$airport->name}{$zoneName}");
} else {
$this->warn("{$airport->name} — giving up after {$attempts} attempts".$response->body());
}
}
});
$this->info('Done!');
}
}
+170
View File
@@ -0,0 +1,170 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class UpDb extends Command
{
protected $signature = 'db:updb
{--no-backup : Skip saving a local backup before wiping}
{--force : Skip confirmation prompt}';
protected $description = 'Download the production database and replace the local database with it';
public function handle(): int
{
if (! $this->option('force') && ! $this->confirm('This will wipe your local database and replace it with production. Are you sure?')) {
$this->info('Aborted.');
return self::SUCCESS;
}
$local = $this->connectionConfig('local');
$production = $this->connectionConfig('production');
$timestamp = now()->format('Y_m_d_His');
$dumpPath = storage_path("app/private/db_dumps/production_{$timestamp}.dump");
$backupPath = storage_path("app/private/db_dumps/local_backup_{$timestamp}.dump");
if (! is_dir(storage_path('app/private/db_dumps'))) {
mkdir(storage_path('app/private/db_dumps'), 0755, true);
}
// Step 1: Dump production
$this->info('Dumping production database...');
$dumpResult = $this->pgDump($production, $dumpPath);
if ($dumpResult !== 0) {
$this->error('Failed to dump production database.');
return self::FAILURE;
}
$this->info("Production dump saved to: {$dumpPath}");
// Step 2: Back up local (unless skipped)
if (! $this->option('no-backup')) {
$this->info('Backing up local database...');
$backupResult = $this->pgDump($local, $backupPath);
if ($backupResult !== 0) {
$this->error('Failed to back up local database. Aborting to be safe. Use --no-backup to skip.');
return self::FAILURE;
}
$this->info("Local backup saved to: {$backupPath}");
}
// Step 3: Drop and recreate the local database
$this->info('Wiping local database...');
$this->dropAndRecreateLocalDatabase($local);
// Step 4: Restore production dump into local
$this->info('Restoring production dump to local database...');
$restoreResult = $this->pgRestore($local, $dumpPath);
if ($restoreResult !== 0) {
$this->error('Restore failed. Your local backup is at: ' . ($this->option('no-backup') ? 'N/A (backup was skipped)' : $backupPath));
return self::FAILURE;
}
$this->info('Done. Local database now mirrors production.');
return self::SUCCESS;
}
private function connectionConfig(string $type): array
{
$connection = $type === 'production' ? 'pgsql_production' : config('database.default');
return [
'host' => config("database.connections.{$connection}.host"),
'port' => config("database.connections.{$connection}.port"),
'database' => config("database.connections.{$connection}.database"),
'username' => config("database.connections.{$connection}.username"),
'password' => config("database.connections.{$connection}.password"),
];
}
private function pgDump(array $config, string $outputPath): int
{
$pgpass = $this->writePgPass($config);
$command = sprintf(
'pg_dump -Fc -h %s -p %s -U %s %s -f %s',
escapeshellarg($config['host']),
escapeshellarg($config['port']),
escapeshellarg($config['username']),
escapeshellarg($config['database']),
escapeshellarg($outputPath),
);
$resultCode = $this->runWithPgPass($pgpass, $command);
unlink($pgpass);
return $resultCode;
}
private function pgRestore(array $config, string $dumpPath): int
{
$pgpass = $this->writePgPass($config);
$command = sprintf(
'pg_restore -h %s -p %s -U %s -d %s --no-owner --no-privileges %s',
escapeshellarg($config['host']),
escapeshellarg($config['port']),
escapeshellarg($config['username']),
escapeshellarg($config['database']),
escapeshellarg($dumpPath),
);
$resultCode = $this->runWithPgPass($pgpass, $command);
unlink($pgpass);
return $resultCode;
}
/**
* Write a temporary pgpass file and return its path.
* This is the cross-platform alternative to PGPASSWORD which doesn't work on Windows.
*/
private function writePgPass(array $config): string
{
// Escape any colons or backslashes in the password per pgpass format rules
$password = str_replace(['\\', ':'], ['\\\\', '\\:'], $config['password']);
$content = "{$config['host']}:{$config['port']}:*:{$config['username']}:{$password}";
$path = tempnam(sys_get_temp_dir(), 'pgpass_');
file_put_contents($path, $content);
chmod($path, 0600);
return $path;
}
private function runWithPgPass(string $pgpassFile, string $command): int
{
// PGPASSFILE is supported on all platforms including Windows
putenv("PGPASSFILE={$pgpassFile}");
passthru($command, $resultCode);
putenv('PGPASSFILE');
return $resultCode;
}
private function dropAndRecreateLocalDatabase(array $config): void
{
$database = $config['database'];
// Connect to the postgres maintenance database to drop/recreate
$pdo = new \PDO(
"pgsql:host={$config['host']};port={$config['port']};dbname=postgres",
$config['username'],
$config['password'],
);
$pdo->exec("SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = " . $pdo->quote($database));
$pdo->exec("DROP DATABASE IF EXISTS " . '"' . $database . '"');
$pdo->exec("CREATE DATABASE " . '"' . $database . '"');
}
}
@@ -0,0 +1,33 @@
<?php
namespace App\Http\Controllers;
use App\Models\Achievement;
use App\Models\User;
use Illuminate\Http\Request;
use Inertia\Inertia;
class AchievementController extends Controller
{
public function index(User $user)
{
$achievements = Achievement::with(['category', 'difficulty'])
->get()
->groupBy(fn(Achievement $a) => $a->category->name)
->map(fn($group) => $group->sortBy('id')->values());
$userAchievements = $user->achievements()
->with('achievement')
->orderBy('achievement_id')
->get()
->keyBy('achievement_id');
return Inertia::render('UserAchievements', [
'user' => $user,
'canEdit' => auth()->id() === $user->id,
'isFollowing' => auth()->check() && auth()->user()->isFollowing($user),
'achievements' => $achievements,
'userAchievements' => $userAchievements,
]);
}
}
@@ -0,0 +1,12 @@
<?php
namespace App\Http\Controllers;
use App\Models\Airline;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Http\Request;
class AirlineController extends Controller
{
}
@@ -0,0 +1,76 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\ApiController;
use App\Http\Controllers\Controller;
use App\Models\Airline;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class AirlineApiController extends ApiController
{
const array CONDOR_LOGOS = ['BEACH', 'ISLAND', 'PASSION', 'SEA', 'SUNSHINE'];
public function getAirlineLogo(?Airline $airline)
{
$logoFile = $airline?->logo ?? 'blank.png';
$cacheLimit = 60 * 60 * 24;
if ($airline?->internal_name == 'condor') {
$logoKey = array_rand(self::CONDOR_LOGOS);
$logoFile = 'DE_' . self::CONDOR_LOGOS[$logoKey] . '.png';
$cacheLimit = 1;
}
$path = 'images/logos/tail/' . $logoFile;
if (!Storage::disk('local')->exists($path)) {
$path = 'images/logos/tail/blank.png';
}
$fullPath = Storage::disk('local')->path($path);
$lastModified = filemtime($fullPath);
return response()->file($fullPath, [
'Content-Type' => 'image/png',
'Cache-Control' => 'public, max-age='.$cacheLimit, // 24 hours
'Last-Modified' => gmdate('D, d M Y H:i:s', $lastModified) . ' GMT',
'ETag' => md5($path . $lastModified),
]);
}
public function getLogoByInternalName(string $internalName){
$airline = Airline::where('internal_name', $internalName)
->first();
return $this->getAirlineLogo($airline);
}
function parseAirlineData(Airline $airline){
$countryCode = $airline->country->code;
$result = $airline->toArray();
unset($result['id']);
unset($result['logo']);
unset($result['country_id']);
unset($result['country']);
$result['slug'] = $result['internal_name'];
unset($result['internal_name']);
$result['country_code'] = $countryCode;
return $result;
}
function getByCode(string $code){
$lookupColumn = strlen($code) === 3 ? 'ICAO_code' : 'IATA_code';
$airlines = Airline::where($lookupColumn, strtoupper($code))->get()->map(fn($airline) => $this->parseAirlineData($airline));
return response()->json($airlines);
}
function get(string $internalName){
$airline = Airline::where('internal_name', $internalName)->first();
return response()->json($this->parseAirlineData($airline));
}
}
@@ -0,0 +1,60 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\ApiController;
use App\Models\User;
use App\Models\UserFlight;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
class UserApiController extends ApiController
{
public function nextFlight(string $username): JsonResponse
{
$user = User::where('name', 'ilike', $username)->first();
if (!$user) {
return response()->json(['message' => 'User not found'], 404);
}
$flight = UserFlight::with(['departureAirport', 'arrivalAirport', 'airline', 'aircraft'])
->where('user_id', $user->id)
->where('departure_date', '>', now()->utc())
->orderBy('departure_date', 'asc')
->first();
if (!$flight) {
return response()->json(['message' => 'No upcoming flights found'], 404);
}
$departure = Carbon::parse($flight->departure_date)->setTimezone($flight->departureAirport->timezone);
$arrival = Carbon::parse($flight->arrival_date)->setTimezone($flight->arrivalAirport->timezone);
return response()->json([
'departureAirportCode' => $flight->departureAirport->iata_code,
'departureCity' => $flight->departureAirport->municipality,
'departureDateReadable' => $departure->format('F j'),
'departureTime' => $departure->format('H:i'),
'arrivalAirportCode' => $flight->arrivalAirport->iata_code,
'arrivalCity' => $flight->arrivalAirport->municipality,
'arrivalDateReadable' => $arrival->format('F j'),
'arrivalTime' => $arrival->format('H:i'),
'flightNumber' => $flight->flight_number,
'airlineName' => $flight->airline->name,
'aircraftType' => $flight->aircraft->manufacturer_code . ' ' . $flight->aircraft->model_full_name,
'logoUrl' => $flight->airline?->logo_url ?? 'undefined',
]);
}
public function flights(string $username): JsonResponse
{
$user = User::where('name', 'ilike', $username)->first();
if (!$user) {
return response()->json(['message' => 'User not found'], 404);
}
return response()->json($user->FlightController()->flights());
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ApiController extends Controller
{
}
@@ -8,7 +8,9 @@ use Illuminate\Auth\Events\Registered;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rules;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
@@ -31,12 +33,21 @@ class RegisteredUserController extends Controller
*/
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => 'required|string|max:255',
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:32|alpha_dash',
'email' => 'required|string|lowercase|email|max:255|unique:'.User::class,
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$validator->after(function ($validator) use ($request) {
if (User::whereRaw(DB::raw('LOWER(name) = ?'), [strtolower($request->name)])->exists()) {
$validator->errors()->add('name', 'The name has already been taken.');
}
});
$validator->validate();
$user = User::create([
'name' => $request->name,
'email' => $request->email,
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace App\Http\Controllers;
use App\Models\UserAction;
use Illuminate\Http\Request;
use Inertia\Inertia;
class FeedController extends Controller
{
public function view()
{
$user = auth()->user();
$followeeIds = $user->following()->pluck('followee_id');
$feed = UserAction::whereIn('user_id', $followeeIds)
->whereNotIn('type', ['flight_deleted'])
->with([
'user',
])
->latest()
->limit(50)
->get();
return Inertia::render('Feed', [
'user' => $user,
'feed' => $feed,
]);
}
}
+277
View File
@@ -0,0 +1,277 @@
<?php
namespace App\Http\Controllers;
use App\Models\Aircraft;
use App\Models\Airline;
use App\Models\Airport;
use App\Models\CrewType;
use App\Models\FlightClass;
use App\Models\FlightReason;
use App\Models\SeatType;
use App\Models\UserAction;
use App\Models\UserFlight;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class FlightController extends Controller
{
use AuthorizesRequests;
public function rules(): array
{
return [
'flight_number' => ['nullable', 'string', 'max:10'],
'departure_date' => ['required', 'date'],
'arrival_date' => ['required', 'date'],
'from_id' => ['required', 'integer', 'exists:airports,id'],
'to_id' => ['required', 'integer', 'exists:airports,id'],
'airline_id' => ['nullable', 'integer', 'exists:airlines,id'],
'aircraft_id' => ['nullable', 'integer', 'exists:aircraft,id'],
'aircraft_registration' => ['nullable', 'string', 'max:10'],
'seat_number' => ['nullable', 'string', 'max:10'],
'seat_type_id' => ['integer', 'exists:seat_types,id'],
'flight_class_id' => ['integer', 'exists:flight_classes,id'],
'flight_reason_id' => ['integer', 'exists:flight_reasons,id'],
'note' => ['nullable', 'string', 'max:5000'],
'auto_update' => ['boolean'],
'crew_type_id' => ['nullable', 'exists:crew_types,id'],
];
}
public function lookup(Request $request)
{
$number = strtoupper(trim($request->query('number', '')));
// Extract the airline code prefix — letters at the start e.g. "QF" from "QF1"
preg_match('/^([A-Z]{2,3})/', $number, $matches);
$code = $matches[1] ?? null;
$isIata = strlen($code) === 2;
$codeColumn = $isIata ? 'IATA_code' : 'ICAO_code';
$airlines = $code
? Airline::where($codeColumn, $code)
->get()
->map(fn ($airline) => ['value' => $airline->id, 'title' => $airline->display_name, 'logo_url' => $airline->logo_url])
->values()
->toArray()
: collect()->toArray();
return response()->json([
'airline_options' => $airlines,
'from_options' => [],
'to_options' => [],
'aircraft_options' => [],
]);
}
private function convertedDates(array $validated): array
{
$departureAirport = Airport::find($validated['from_id']);
$arrivalAirport = Airport::find($validated['to_id']);
return [
Carbon::createFromFormat('Y-m-d\TH:i', $validated['departure_date'], $departureAirport->timezone)->utc(),
Carbon::createFromFormat('Y-m-d\TH:i', $validated['arrival_date'], $arrivalAirport->timezone)->utc(),
];
}
private function recordChanges(UserFlight $flight, array $dirty, array $original, array $updated): void
{
$changes = [];
foreach ($dirty as $field => $newValue) {
$changes[] = $this->formatChange($field, $flight->getOriginal($field), $newValue);
}
UserAction::create([
'user_id' => $flight->user_id,
'data' => [
'changes' => $changes,
'original' => $original,
'updated' => $updated,
],
'type' => 'flight_updated',
]);
}
private array $labelCache = [];
private function resolveLabel(string $field, mixed $value): string
{
if (is_null($value)) {
return 'none';
}
$cacheKey = "{$field}:{$value}";
if (isset($this->labelCache[$cacheKey])) {
return $this->labelCache[$cacheKey];
}
$label = match($field) {
'airline_id' => Airline::find($value)?->display_name ?? $value,
'departure_airport_id',
'arrival_airport_id' => Airport::find($value)?->display_name ?? $value,
'aircraft_id' => Aircraft::find($value)?->display_name_short ?? $value,
'seat_type_id' => SeatType::find($value)?->name ?? $value,
'flight_class_id' => FlightClass::find($value)?->name ?? $value,
'flight_reason_id' => FlightReason::find($value)?->name ?? $value,
'crew_type_id' => CrewType::find($value)?->name ?? $value,
'departure_date',
'arrival_date' => Carbon::parse($value)->format('j F Y \a\t H:iA'),
default => (string) $value,
};
return $this->labelCache[$cacheKey] = $label;
}
private function formatChange(string $field, mixed $from, mixed $to): array
{
$label = str($field)->replace('_id', '')->replace('_', ' ')->title();
$fromLabel = $this->resolveLabel($field, $from);
$toLabel = $this->resolveLabel($field, $to);
return [
'field' => $field,
'from' => $fromLabel,
'to' => $toLabel,
];
}
private function flightPayload(array $validated): array
{
[$departureUtc, $arrivalUtc] = $this->convertedDates($validated);
return [
'departure_date' => $departureUtc,
'arrival_date' => $arrivalUtc,
'flight_number' => $validated['flight_number'],
'departure_airport_id' => $validated['from_id'],
'arrival_airport_id' => $validated['to_id'],
'airline_id' => $validated['airline_id'],
'aircraft_id' => $validated['aircraft_id'],
'aircraft_registration' => $validated['aircraft_registration'],
'seat_number' => $validated['seat_number'],
'seat_type_id' => $validated['seat_type_id'],
'flight_class_id' => $validated['flight_class_id'],
'flight_reason_id' => $validated['flight_reason_id'],
'note' => $validated['note'],
'auto_update' => $validated['auto_update'],
'crew_type_id' => $validated['crew_type_id'],
];
}
public function store(Request $request)
{
$validated = $request->validate($this->rules());
$newFlight = auth()->user()->flights()->create($this->flightPayload($validated));
UserAction::create([
'user_id' => $newFlight->user_id,
'type' => $newFlight->departure_date->isFuture() ? 'flight_booked' : 'flight_logged',
'data' => [
'flight' => $newFlight->snapshot($newFlight->id),
],
]);
return redirect()->route('profile.departure-board', [Auth::user()->name, $newFlight->id]);
}
public function update(Request $request, UserFlight $flight)
{
$this->authorize('update', $flight);
$validated = $request->validate($this->rules());
$flight->fill($this->flightPayload($validated));
if (!$flight->isDirty()) {
return redirect()->route('profile.departure-board', [Auth::user()->name, $flight->id]);
}
$dirty = $flight->getDirty();
$original = $flight->snapshot($flight->id);
$flight->save();
$updated = $flight->snapshot($flight->id);
$this->recordChanges($flight, $dirty, $original, $updated);
return redirect()->route('profile.departure-board', [Auth::user()->name, $flight->id]);
}
public function delete(UserFlight $flight)
{
$this->authorize('delete', $flight);
$snapshot = $this->flightSnapshot($flight->id);
if(now()->utc()->isBefore($flight->departure_date)){
$action = 'flight_deleted';
} else {
$action = 'flight_cancelled';
}
UserAction::create([
'user_id' => $flight->user_id,
'type' => $action,
'data' => [
'flight' => $snapshot,
]
]);
$flight->delete();
return redirect()->route('profile.departure-board', [Auth::user()->name]);
}
public function staticData() : array {
return [
'seat_types' => SeatType::orderBy('id')->get()->toArray(),
'flight_reasons' => FlightReason::orderBy('id')->get()->toArray(),
'flight_classes' => FlightClass::orderBy('id')->get()->toArray(),
'crew_types' => CrewType::orderBy('id')->get()->toArray(),
];
}
public function add(){
return Inertia::render('AddFlight', $this->staticData());
}
public function edit(UserFlight $flight)
{
$this->authorize('update', $flight);
$flight->load('airline', 'aircraft', 'departureAirport.region.country', 'arrivalAirport.region.country', 'seatType', 'flightClass', 'flightReason');
$flightData = [
'id' => $flight->id,
'flight_number' => $flight->flight_number,
'departure_date' => $flight->departure_date->setTimezone($flight->departureAirport->timezone)->format('Y-m-d\TH:i'),
'arrival_date' => $flight->arrival_date->setTimezone($flight->arrivalAirport->timezone)->format('Y-m-d\TH:i'),
'aircraft_registration' => $flight->aircraft_registration,
'seat_number' => $flight->seat_number,
'note' => $flight->note,
'auto_update' => $flight->auto_update,
'seat_type' => $flight->seatType->toArray(),
'flight_class' => $flight->flightClass->toArray(),
'crew_type' => $flight->crewType?->toArray() ?? [],
'flight_reason' => $flight->flightReason->toArray(),
'airline_options' => $flight->airline
? [['value' => $flight->airline->id, 'title' => $flight->airline->display_name, 'logo_url' => $flight->airline->logo_url]]
: [],
'from_options' => [['value' => $flight->departureAirport->id, 'title' => $flight->departureAirport->display_name, 'country_code' => strtolower($flight->departureAirport->region->country->code)]],
'to_options' => [['value' => $flight->arrivalAirport->id, 'title' => $flight->arrivalAirport->display_name, 'country_code' => strtolower($flight->arrivalAirport->region->country->code)]],
'aircraft_options' => $flight->aircraft
? [['value' => $flight->aircraft->id, 'title' => $flight->aircraft->display_name]]
: [],
];
return Inertia::render('AddFlight', [
'flight' => $flightData,
...$this->staticData(),
]);
}
}
@@ -0,0 +1,407 @@
<?php
namespace App\Http\Controllers;
use App\Models\Aircraft;
use App\Models\Airline;
use App\Models\Airport;
use App\Models\FlightClass;
use App\Models\FlightReason;
use App\Models\ImportedFlight;
use App\Models\SeatType;
use App\Models\UserAction;
use App\Models\UserFlight;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Inertia\Inertia;
class FlightImportController extends Controller
{
private function formatTime(?string $time): string
{
if (!$time) return '00:00';
[$hours, $minutes] = explode(':', $time);
return str_pad($hours, 2, '0', STR_PAD_LEFT) . ':' . $minutes;
}
private function selectOptions($model): array
{
return $model::orderBy('id')
->get(['id', 'name'])
->map(fn($item) => ['value' => $item->id, 'title' => $item->name])
->values()
->toArray();
}
public function getPossibleAircraft(string $aircraftQuery) {
preg_match('/\((\w+)\)/', $aircraftQuery, $matches);
$designator = $matches[1] ?? null;
$sortOverrides = [
'B788' => "CASE WHEN model_full_name ILIKE '%BBJ%' THEN 1 ELSE 0 END",
'B789' => "CASE WHEN model_full_name ILIKE '%BBJ%' THEN 1 ELSE 0 END",
];
if(!$designator){
$aircraft = [];
} else {
$aircraft = Aircraft::when($designator, fn($query) => $query->where('designator', 'ilike', $designator))
->when(
isset($sortOverrides[$designator]),
fn($q) => $q->orderByRaw($sortOverrides[$designator])
)
->orderBy('model_full_name')
->limit(10)
->get(['id', 'manufacturer_code', 'model_full_name', 'designator'])
->map(fn($aircraft) => [
'value' => $aircraft->id,
'title' => $aircraft->display_name,
])
->values()
->toArray();
}
return $aircraft;
}
public function getPossibleAirports(string $airportQuery) {
preg_match('/\((\w{3})\/(\w{4})\)/', $airportQuery, $matches);
$iata = $matches[1] ?? null;
$icao = $matches[2] ?? null;
if (!$iata && !$icao) {
return [];
}
$airports = Airport::with('region.country')
->where(function ($q) use ($iata, $icao) {
$q->where('iata_code', 'ilike', $iata)
->orWhere('icao_code', 'ilike', $icao);
})
->orderByRaw("
CASE
WHEN iata_code = ? AND icao_code = ? THEN 0
WHEN iata_code = ? THEN 1
WHEN icao_code = ? THEN 2
ELSE 3
END
", [$iata, $icao, $iata, $icao])
->limit(10)
->orderBy('id')
->get(['id', 'name', 'municipality', 'iata_code', 'icao_code', 'region_id'])
->map(fn(Airport $airport) => [
'value' => $airport->id,
'title' => $airport->display_name,
'country_code' => strtolower($airport?->region->country->code ?? ''),
])
->values()
->toArray();
return $airports;
}
public function getPossibleAirlines(string $airlineQuery) {
preg_match('/\((\w{2,3})\/(\w{3,4})\)/', $airlineQuery, $matches);
$iata = $matches[1] ?? null;
$icao = $matches[2] ?? null;
if(!$iata && !$icao){
return [];
}
$airlines = Airline::when($iata || $icao, function ($query) use ($iata, $icao) {
$query->orderByRaw("
CASE
WHEN \"IATA_code\" = ? AND \"ICAO_code\" = ? THEN 0
WHEN \"IATA_code\" = ? THEN 1
WHEN \"ICAO_code\" = ? THEN 2
ELSE 3
END
", [$iata, $icao, $iata, $icao])
->where(function ($q) use ($iata, $icao) {
$q->where('IATA_code', $iata)
->orWhere('ICAO_code', $icao);
});
})
->orderByDesc('active')
->limit(10)
->get(['id', 'name', 'IATA_code', 'ICAO_code', 'internal_name'])
->map(fn($airline) => [
'value' => $airline->id,
'title' => $airline->display_name,
'logo_url' => $airline->logo_url,
])
->values()
->toArray();
return $airlines;
}
public function reconcile(Request $request)
{
$user = Auth::user();
$flightToReconcile = ImportedFlight::where('user_id', $user->id)->orderBy('date', 'asc')->first();
if (!$flightToReconcile) {
return null;
}
$date = null;
if ($flightToReconcile->date) {
$date = Carbon::createFromFormat('Y-m-d', $flightToReconcile->date)->format('Y-m-d');
}
return [
'imported_flight_id' => $flightToReconcile->id,
'flight_classes' => $this->selectOptions(FlightClass::class),
'flight_reasons' => $this->selectOptions(FlightReason::class),
'seat_types' => $this->selectOptions(SeatType::class),
'flight_number' => $flightToReconcile->flight_number ?? '',
'date' => $date ?? '',
'dep_time' => $this->formatTime($flightToReconcile->dep_time),
'arr_time' => $this->formatTime($flightToReconcile->arr_time),
'duration' => $this->formatTime($flightToReconcile->duration),
'registration' => $flightToReconcile->registration ?? '',
'note' => $flightToReconcile->note ?? '',
'seat_number' => $flightToReconcile->seat_number ?? '',
'flight_class' => $flightToReconcile->flight_class ?? '',
'seat_type' => $flightToReconcile->seat_type ?? '',
'flight_reason' => $flightToReconcile->flight_reason ?? '',
'airline_options' => $this->getPossibleAirlines($flightToReconcile->airline ?? ''),
'to_options' => $this->getPossibleAirports($flightToReconcile->to ?? ''),
'from_options' => $this->getPossibleAirports($flightToReconcile->from ?? ''),
'aircraft_options' => $this->getPossibleAircraft($flightToReconcile->aircraft ?? ''),
];
}
public function save(Request $request)
{
$validated = $request->validate([
'date' => 'required|date',
'imported_flight_id' => 'required|exists:imported_flights,id',
'flight_number' => 'nullable|string',
'from_id' => 'required|integer|exists:airports,id',
'to_id' => 'required|integer|exists:airports,id',
'dep_time' => 'nullable|date_format:H:i',
'arr_time' => 'nullable|date_format:H:i',
'duration' => 'required|date_format:H:i',
'airline_id' => 'nullable|integer|exists:airlines,id',
'aircraft_id' => 'nullable|integer|exists:aircraft,id',
'registration' => 'nullable|string',
'seat_number' => 'nullable|string',
'seat_type_id' => 'required|integer|exists:seat_types,id',
'flight_class_id' => 'required|integer|exists:flight_classes,id',
'flight_reason_id' => 'required|integer|exists:flight_reasons,id',
'note' => 'nullable|string',
], [
'imported_flight_id.required' => 'The flight you are trying to reconcile needs to be reimported or refreshed.',
'from_id.required' => 'Please select a departure airport.',
'to_id.required' => 'Please select an arrival airport.',
'dep_time.date_format' => 'Departure time must be in HH:MM format, i.e: 01:25',
'arr_time.date_format' => 'Arrival time must be in HH:MM format, i.e: 12:25',
'duration.date_format' => 'Must be in HH:MM format, e.g: 03:37',
'duration.required' => 'A duration is required to be able to accurately calculate the arrival date',
]);
$user = Auth::user();
$departureAirport = Airport::find($validated['from_id']);
$arrivalAirport = Airport::find($validated['to_id']);
// Parse departure in local airport timezone, then convert to UTC
$depTime = $validated['dep_time'] ?? '00:00';
$departure = Carbon::createFromFormat(
'Y-m-d H:i',
$validated['date'] . ' ' . $depTime,
$departureAirport->timezone
)->utc();
// Calculate duration-based arrival in UTC
[$durationHours, $durationMinutes] = explode(':', $validated['duration']);
$durationArrival = $departure->copy()
->addHours((int) $durationHours)
->addMinutes((int) $durationMinutes);
// If arrival time provided, parse it in arrival airport timezone and convert to UTC
if (!empty($validated['arr_time'])) {
$arrival = Carbon::createFromFormat(
'Y-m-d H:i',
$validated['date'] . ' ' . $validated['arr_time'],
$arrivalAirport->timezone
)->utc();
// If arrival is not after departure, fall back to duration-based arrival
if ($arrival->lte($departure)) {
$arrival = $durationArrival;
}
} else {
$arrival = $durationArrival;
}
$newFlight = UserFlight::create([
'user_id' => $user->id,
'departure_date' => $departure,
'arrival_date' => $arrival,
'flight_number' => $validated['flight_number'],
'departure_airport_id' => $validated['from_id'],
'arrival_airport_id' => $validated['to_id'],
'airline_id' => $validated['airline_id'] ?? null,
'aircraft_id' => $validated['aircraft_id'] ?? null,
'aircraft_registration' => $validated['registration'] ?? null,
'seat_number' => $validated['seat_number'] ?? null,
'seat_type_id' => $validated['seat_type_id'] ?? 0,
'flight_class_id' => $validated['flight_class_id'] ?? 0,
'flight_reason_id' => $validated['flight_reason_id'] ?? 0,
'note' => $validated['note'] ?? null,
]);
UserAction::create([
'user_id' => $newFlight->user_id,
'type' => $newFlight->departure_date->isFuture() ? 'flight_booked' : 'flight_imported',
'data' => [
'flight' => $newFlight->snapshot($newFlight->id),
],
]);
ImportedFlight::destroy($validated['imported_flight_id']);
return to_route('reconcile');
}
private function validateCsvFormat(string $path): ?string
{
$handle = fopen($path, 'r');
// Must have empty first line
$firstLine = fgetcsv($handle);
if (!empty(array_filter($firstLine))) {
fclose($handle);
return 'CSV must match the MyFlightRadar24 export format.';
}
// Validate headers
$expectedHeaders = [
'date', 'flight_number', 'from', 'to', 'dep_time', 'arr_time',
'duration', 'airline', 'aircraft', 'registration', 'seat_number',
'seat_type', 'flight_class', 'flight_reason', 'note',
'dep_id', 'arr_id', 'airline_id', 'aircraft_id'
];
$headers = array_map(
fn($h) => strtolower(trim(str_replace([' ', '"'], ['_', ''], $h))),
fgetcsv($handle)
);
if ($headers !== $expectedHeaders) {
fclose($handle);
return 'CSV headers do not match the expected format.';
}
// Validate data rows
$row = 1;
while (($data = fgetcsv($handle)) !== false) {
$row++;
if (count($data) !== count($expectedHeaders)) {
fclose($handle);
return "Row {$row} has the wrong number of columns.";
}
$combined = array_combine($expectedHeaders, $data);
if (empty($combined['date']) || empty($combined['from']) || empty($combined['to'])) {
fclose($handle);
return "Row {$row} is missing a required field (date, from, or to).";
}
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $combined['date'])) {
fclose($handle);
return "Row {$row} has an invalid date format. Expected YYYY-MM-DD, got '{$combined['date']}'.";
}
}
fclose($handle);
return null;
}
public function store(Request $request)
{
try {
$request->validate([
'csv' => ['required', 'file', 'mimes:csv,txt', 'max:10240'],
]);
$path = $request->file('csv')->getRealPath();
$validationError = $this->validateCsvFormat($path);
if ($validationError) {
return response()->json(['message' => $validationError], 422);
}
$handle = fopen($path, 'r');
fgetcsv($handle);
// Read and normalise header row
$headers = array_map(
fn($h) => strtolower(trim(str_replace(' ', '_', $h))),
fgetcsv($handle)
);
\Log::debug('CSV headers', $headers);
$firstRow = fgetcsv($handle);
\Log::debug('First row', $firstRow ?? ['empty']);
\Log::debug('Header count: ' . count($headers) . ', Row count: ' . count($firstRow ?? []));
$map = [
'date' => 'date',
'flight_number' => 'flight_number',
'from' => 'from',
'to' => 'to',
'dep_time' => 'dep_time',
'arr_time' => 'arr_time',
'duration' => 'duration',
'airline' => 'airline',
'aircraft' => 'aircraft',
'registration' => 'registration',
'seat_number' => 'seat_number',
'seat_type' => 'seat_type',
'flight_class' => 'flight_class',
'flight_reason' => 'flight_reason',
'note' => 'note',
];
$userId = Auth::id();
$imported = 0;
while (($row = fgetcsv($handle)) !== false) {
if (count($row) !== count($headers)) {
continue; // skip malformed rows
}
$raw = array_combine($headers, $row);
$data = ['user_id' => $userId];
foreach ($map as $csvKey => $column) {
$data[$column] = $raw[$csvKey] ?? null;
}
ImportedFlight::create($data);
$imported++;
}
fclose($handle);
return response()->json(['imported' => $imported]);
} catch (\Exception $e) {
return response()->json(['message' => $e->getMessage()], 500);
}
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Models\UserFlight;
use App\Http\Resources\UserFlightResource;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;
class FlightProfileController extends Controller
{
public function profileData(User $user, string $view, ?int $selectedFlightId = null) : array {
return [
'user' => $user,
'canEdit' => auth()->check() && auth()->id() === $user->id,
'initialView' => $view,
'selectedFlightId' => $selectedFlightId,
'flight_api_url' => '/data/user/'.$user->name.'/flights',
'isFollowing' => auth()->check() && auth()->user()->isFollowing($user),
];
}
public function departureBoard(User $user, ?UserFlight $flight = null){
$profileData = $this->profileData($user, 'board', $flight?->id);
return Inertia::render('UserProfile', $profileData);
}
public function map(User $user){
$profileData = $this->profileData($user, 'map');
return Inertia::render('UserProfile', $profileData);
}
public function boardingPasses(User $user){
$profileData = $this->profileData($user, 'passes');
return Inertia::render('UserProfile', $profileData);
}
public function view(User $user)
{
return $this->departureBoard($user);
}
}
+73 -26
View File
@@ -8,38 +8,85 @@ use Illuminate\Support\Facades\Storage;
class LogoController extends Controller
{
public function getAirlineLogo(?Airline $airline){
$logoFile = $airline?->logo ?? 'blank.png';
$path = 'images/logos/tail/' . $logoFile;
if (!Storage::disk('local')->exists($path)) {
$path = 'images/logos/tail/blank.png';
public static function deduplicateLogo(string $logo, array $correctInternalNames)
{
$log = fn(string $message) => print($message . PHP_EOL);
if (empty($correctInternalNames)) {
$nulled = Airline::where('logo', $logo)->get(['name', 'internal_name']);
Airline::where('logo', $logo)->update(['logo' => null]);
foreach ($nulled as $airline) {
$log(" Logo nulled: {$airline->name} ({$airline->internal_name})");
}
return;
}
return response()->file(Storage::disk('local')->path($path), [
'Content-Type' => 'image/png',
]);
$existing = Airline::whereIn('internal_name', $correctInternalNames)
->pluck('internal_name')
->toArray();
$missing = array_diff($correctInternalNames, $existing);
if (!empty($missing)) {
throw new \InvalidArgumentException(
'The following internal names do not exist in the database: ' . implode(', ', $missing)
);
}
public function getLogoByCode(string $code){
$nulled = Airline::where('logo', $logo)
->whereNotIn('internal_name', $correctInternalNames)
->get(['name', 'internal_name']);
$column = strlen($code) == 2
? 'IATA_code'
: 'ICAO_code';
Airline::where('logo', $logo)
->whereNotIn('internal_name', $correctInternalNames)
->update(['logo' => null]);
$airline = Airline::where($column, strtoupper($code))
->whereNotNull('logo')
->where('active', true)
->latest('id')
->first();
if (!$airline) {
$airline = Airline::where($column, strtoupper($code))
->whereNotNull('logo')
->latest('id')
->first();
}
return $this->getAirlineLogo($airline);
foreach ($nulled as $airline) {
$log(" Logo nulled: {$airline->name} ({$airline->internal_name})");
}
}
public static function nullMissingLogoFiles()
{
$log = fn(string $message) => print($message . PHP_EOL);
$airlines = Airline::whereNotNull('logo')->get(['id', 'name', 'logo']);
foreach ($airlines as $airline) {
$path = storage_path('app/private/images/logos/tail/' . $airline->logo);
if (!file_exists($path)) {
$airline->update(['logo' => null]);
$log(" Logo nulled (file missing): {$airline->name}{$airline->logo}");
}
}
}
public static function renameLogoFiles()
{
$log = fn(string $message) => print($message . PHP_EOL);
$airlines = Airline::whereNotNull('logo')->get(['id', 'name', 'internal_name', 'logo']);
foreach ($airlines as $airline) {
$expectedName = $airline->internal_name . '.png';
if ($airline->logo === $expectedName) {
continue;
}
$oldPath = storage_path('app/private/images/logos/tail/' . $airline->logo);
$newPath = storage_path('app/private/images/logos/tail/' . $expectedName);
if (!file_exists($oldPath)) {
$log(" Skipping (file missing): {$airline->name}{$airline->logo}");
continue;
}
rename($oldPath, $newPath);
$airline->update(['logo' => $expectedName]);
$log(" Renamed: {$airline->logo}{$expectedName} ({$airline->name})");
}
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Http\Controllers;
use App\Models\Notification;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\Request;
class NotificationController extends Controller
{
use AuthorizesRequests;
public function markRead(Request $request, Notification $notification)
{
$this->authorize('update', $notification);
$notification->markAsRead();
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
namespace App\Http\Controllers;
use App\Models\Aircraft;
use App\Models\Airline;
use App\Models\Airport;
use Illuminate\Http\Request;
class SearchController extends Controller
{
public function airlines(){
$q = request('q', '');
return Airline::orderByDesc('active')
->where(function ($query) use ($q) {
$len = strlen($q);
if ($len === 2) {
$query->where('IATA_code', 'ilike', $q);
} elseif ($len === 3) {
$query->where('ICAO_code', 'ilike', $q);
} else {
$query->where('name', 'ilike', "%{$q}%")
->orWhere('IATA_code', 'ilike', "%{$q}%")
->orWhere('ICAO_code', 'ilike', "%{$q}%");
}
})
->limit(50)
->get()
->map(fn($airline) => [
'value' => $airline->id,
'title' => $airline->display_name,
'logo_url' => $airline->logo_url,
])
->values();
}
public function aircraft()
{
$q = request('q', '');
$replacedQuery = str_replace(['A3', 'A2'], ['A-3', 'A-2'], $q);
return Aircraft::where('designator', 'ilike', "%{$q}%")
->orWhereRaw("CONCAT(manufacturer_code, ' ', model_full_name) ilike ?", ["%{$q}%"])
->orWhereRaw("CONCAT(manufacturer_code, ' ', model_full_name) ilike ?", ["%{$replacedQuery}%"])
->limit(200)
->orderBy('id', 'asc')
->get(['id', 'manufacturer_code', 'model_full_name', 'designator'])
->map(fn($aircraft) => [
'value' => $aircraft->id,
'title' => $aircraft->display_name,
])
->values();
}
public function airports()
{
$q = request('q', '');
$len = strlen($q);
if ($len < 3) return [];
return Airport::with('region.country')
->when($len === 3, fn($query) => $query->where('iata_code', 'ilike', $q))
->when($len >= 4, fn($query) => $query->where(function ($sub) use ($q, $len) {
$sub->when($len === 4, fn($s) => $s->where('icao_code', 'ilike', $q))
->orWhere('name', 'ilike', "%{$q}%")
->orWhere('municipality', 'ilike', "%{$q}%");
})->orderByRaw("
CASE
WHEN icao_code = ? THEN 0
WHEN iata_code = ? THEN 1
ELSE 2
END
", [$q, $q]))
->limit(15)
->get(['id', 'name', 'municipality', 'iata_code', 'icao_code', 'region_id'])
->map(fn($airport) => [
'value' => $airport->id,
'title' => $airport->display_name,
'country_code' => strtolower($airport->region->country->code),
])
->values();
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace App\Http\Controllers;
use App\Models\Followee;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function follow(User $user): JsonResponse
{
$existing = Followee::where('user_id', auth()->id())
->where('followee_id', $user->id)
->first();
if ($existing) {
$existing->delete();
return response()->json(['following' => false]);
}
Followee::create([
'user_id' => auth()->id(),
'followee_id' => $user->id,
]);
return response()->json(['following' => true]);
}
}
@@ -0,0 +1,36 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use App\Models\UserFlight;
use Illuminate\Http\Request;
class UserFlightController extends Controller
{
protected User $user;
function __construct(User $user){
$this->user = $user;
}
public function flights(){
return UserFlight::where('user_id', $this->user->id)
->with([
'departureAirport.region.country',
'departureAirport.region.continent',
'arrivalAirport.region.country',
'arrivalAirport.region.continent',
'airline.country',
'airline.alliance',
'aircraft',
'seatType',
'flightReason',
'flightClass',
'crewType'
])
->orderBy('departure_date', 'desc')
->get();
}
}
@@ -31,9 +31,19 @@ class HandleInertiaRequests extends Middleware
{
return [
...parent::share($request),
'logo_api_url' => config('app.logo_api_url'),
'auth' => [
'user' => $request->user(),
],
'achievement_notifications' => fn() => $request->user()
? $request->user()
->notifications()
->with('achievement')
->where('is_achievement', true)
->whereNull('read_at')
->latest()
->get()
: [],
];
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Http\Resources;
use App\Models\UserFlight;
use Carbon\Carbon;
use Illuminate\Http\Resources\Json\JsonResource;
/** @mixin UserFlight */
class UserFlightResource extends JsonResource
{
}
+74
View File
@@ -0,0 +1,74 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
* @property string $name
* @property string $internal_name
* @property string $short_description
* @property string $long_description
* @property string $icon
* @property bool $progressive
* @property string|null $difficulty_description
* @property int $achievement_category_id
* @property int $achievement_difficulty_id
*
* @property-read AchievementCategory $category
* @property-read AchievementDifficulty $difficulty
* @property-read Collection<int, UserAchievement> $userAchievements
* @property-read Collection<int, User> $users
*/
class Achievement extends Model
{
protected $fillable = [
'name',
'internal_name',
'short_description',
'long_description',
'icon',
'progressive',
'difficulty_description',
'achievement_category_id',
'achievement_difficulty_id',
'threshold',
];
protected $casts = [
'progressive' => 'boolean',
'threshold' => 'integer',
];
// ---------------------------------------------------------------
// Relationships
// ---------------------------------------------------------------
public function category(): BelongsTo
{
return $this->belongsTo(AchievementCategory::class, 'achievement_category_id');
}
public function difficulty(): BelongsTo
{
return $this->belongsTo(AchievementDifficulty::class, 'achievement_difficulty_id');
}
public function userAchievements(): HasMany
{
return $this->hasMany(UserAchievement::class, 'achievement_id');
}
/** Users who have unlocked (or are progressing toward) this achievement. */
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'user_achievements')
->withPivot('progress')
->withTimestamps();
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
* @property string $internal_name
* @property string $name
* @property string $description
*
* @property-read Collection<int, Achievement> $achievements
*/
class AchievementCategory extends Model
{
protected $fillable = [
'internal_name',
'name',
'description',
];
// ---------------------------------------------------------------
// Relationships
// ---------------------------------------------------------------
public function achievements(): HasMany
{
return $this->hasMany(Achievement::class, 'achievement_category_id');
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
* @property string $internal_name
* @property string $name
* @property string $description
*
* @property-read Collection<int, Achievement> $achievements
*/
class AchievementDifficulty extends Model
{
protected $fillable = [
'internal_name',
'name',
'description',
];
// ---------------------------------------------------------------
// Relationships
// ---------------------------------------------------------------
public function achievements(): HasMany
{
return $this->hasMany(Achievement::class, 'achievement_difficulty_id');
}
}
+24
View File
@@ -2,6 +2,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
class Aircraft extends Model
@@ -19,4 +20,27 @@ class Aircraft extends Model
protected $casts = [
'engine_count' => 'integer',
];
protected $appends = [
'display_name',
'display_name_short'
];
protected function displayName() : Attribute{
return Attribute::make(
get: function () {
return "{$this->manufacturer_code} {$this->model_full_name} ({$this->designator})";
}
);
}
protected function displayNameShort(): Attribute
{
return Attribute::make(
get: function () {
$name = "{$this->manufacturer_code} {$this->model_full_name}";
return trim(preg_replace('/\s*\(.*?\)/', '', $name));
}
);
}
}
+36 -2
View File
@@ -3,7 +3,9 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Airline extends Model
{
@@ -14,8 +16,8 @@ class Airline extends Model
'ICAO_code',
'name',
'internal_name',
'country_code',
'country_name',
'country_id',
'alliance_id',
'active',
'logo',
];
@@ -25,4 +27,36 @@ class Airline extends Model
];
public $timestamps = false;
protected $appends = [
'display_name',
'logo_url',
];
protected function displayName() : Attribute{
return Attribute::make(
get: function () {
$codes = array_filter([$this->IATA_code, $this->ICAO_code]);
$codeString = count($codes) ? ' (' . implode('/', $codes) . ')' : '';
return "{$this->name}{$codeString}";
}
);
}
protected function logoUrl() : Attribute{
return Attribute::make(
get: function () {
return config('app.logo_api_url') . "/airline/$this->internal_name/logo/tail";
}
);
}
public function alliance(): BelongsTo
{
return $this->belongsTo(Alliance::class);
}
public function country(): BelongsTo
{
return $this->belongsTo(Country::class);
}
}
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Airport extends Model
{
protected $fillable = [
'type',
'name',
'latitude_deg',
'longitude_deg',
'elevation_ft',
'timezone',
'region_id',
'municipality',
'icao_code',
'iata_code',
'local_code',
];
protected $casts = [
'latitude_deg' => 'float',
'longitude_deg' => 'float',
'elevation_ft' => 'integer',
];
protected $appends = [
'display_code',
'display_name',
];
protected function displayName() : Attribute{
return Attribute::make(
get: function () {
$codes = array_filter([$this->iata_code, $this->icao_code]);
$codeString = count($codes) ? ' (' . implode('/', $codes) . ')' : '';
return "{$this->municipality} / {$this->name}{$codeString}";
}
);
}
protected function displayCode(): Attribute
{
return Attribute::make(
get: fn () => $this->iata_code ?? $this->icao_code ?? $this->local_code ?? '---'
);
}
public function region(): BelongsTo
{
return $this->belongsTo(Region::class);
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Alliance extends Model
{
protected $table = 'alliances';
protected $fillable = [
'internal_name',
'name',
];
protected $casts = [
'internal_name' => 'string',
];
public function airlines(): HasMany
{
return $this->hasMany(Airline::class);
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CrewType extends Model
{
protected $table = 'crew_types';
protected $fillable = [
'name',
'internal_name',
];
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class FlightClass extends Model
{
protected $fillable = [
'name',
'internal_name',
];
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class FlightReason extends Model
{
public $timestamps = false;
}
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Followee extends Model
{
protected $fillable = [
'user_id',
'followee_id',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function followee(): BelongsTo
{
return $this->belongsTo(User::class, 'followee_id');
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class ImportedFlight extends Model
{
public $timestamps = false;
protected $fillable = [
'user_id',
'date',
'flight_number',
'from',
'to',
'dep_time',
'arr_time',
'duration',
'airline',
'aircraft',
'registration',
'seat_number',
'seat_type',
'flight_class',
'flight_reason',
'note',
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
+102
View File
@@ -0,0 +1,102 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property int $id
* @property int $user_id
* @property string $title
* @property string $body
* @property string|null $url
* @property bool $is_achievement
* @property int|null $achievement_id
* @property \Carbon\Carbon|null $read_at
* @property \Carbon\Carbon|null $dismissed_at
* @property \Carbon\Carbon|null $expires_at
*
* @property-read User $user
* @property-read Achievement|null $achievement
*
* @method static Builder unread()
* @method static Builder undismissed()
* @method static Builder active()
* @method static Builder forAchievements()
*/
class Notification extends Model
{
protected $fillable = [
'user_id',
'title',
'body',
'url',
'is_achievement',
'achievement_id',
'read_at',
'expires_at',
];
protected $casts = [
'is_achievement' => 'boolean',
'read_at' => 'datetime',
'expires_at' => 'datetime',
];
// ---------------------------------------------------------------
// Relationships
// ---------------------------------------------------------------
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function achievement(): BelongsTo
{
return $this->belongsTo(Achievement::class);
}
// ---------------------------------------------------------------
// Scopes
// ---------------------------------------------------------------
/** Notifications the user hasn't opened yet. */
public function scopeUnread(Builder $query): void
{
$query->whereNull('read_at');
}
/** Not expired (no expiry set, or expiry is in the future). */
public function scopeActive(Builder $query): void
{
$query->where(function (Builder $q) {
$q->whereNull('expires_at')
->orWhere('expires_at', '>', now());
});
}
/** Only achievement notifications. */
public function scopeForAchievements(Builder $query): void
{
$query->where('is_achievement', true);
}
// ---------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------
public function markAsRead(): void
{
if (! $this->read_at) {
$this->update(['read_at' => now()]);
}
}
public function isExpired(): bool
{
return $this->expires_at !== null && $this->expires_at->isPast();
}
}
+5
View File
@@ -19,4 +19,9 @@ class Region extends Model
{
return $this->belongsTo(Country::class);
}
public function continent(): BelongsTo
{
return $this->belongsTo(Continent::class);
}
}
+13
View File
@@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class SeatType extends Model
{
protected $fillable = [
'name',
];
public $timestamps = false;
}
+53 -3
View File
@@ -2,20 +2,26 @@
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Http\Controllers\UserFlightController;
use Database\Factories\UserFactory;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Attributes\Hidden;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use App\Traits\HasAchievements;
use App\Models\Notification;
use Laravel\Sanctum\HasApiTokens;
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable
{
/** @use HasFactory<UserFactory> */
use HasFactory, Notifiable;
use HasFactory, HasAchievements, HasApiTokens;
/**
* Get the attributes that should be cast.
@@ -29,4 +35,48 @@ class User extends Authenticatable
'password' => 'hashed',
];
}
public function achievements(): HasMany
{
return $this->hasMany(UserAchievement::class);
}
public function resolveRouteBinding($value, $field = null): ?User
{
return $this->where('name', 'ilike', $value)->firstOrFail();
}
public function FlightController(): UserFlightController
{
return new UserFlightController($this);
}
public function flights(): HasMany {
return $this->hasMany(UserFlight::class);
}
public function ImportedFlights(): HasMany
{
return $this->hasMany(ImportedFlight::class);
}
public function following(): HasMany
{
return $this->hasMany(Followee::class, 'user_id');
}
public function followers(): HasMany
{
return $this->hasMany(Followee::class, 'followee_id');
}
public function isFollowing(User $user): bool
{
return $this->following()->where('followee_id', $user->id)->exists();
}
public function notifications(): HasMany
{
return $this->hasMany(Notification::class);
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property int $id
* @property int $user_id
* @property int $achievement_id
* @property int|null $progress
*
* @property-read User $user
* @property-read Achievement $achievement
*/
class UserAchievement extends Model
{
protected $fillable = [
'user_id',
'achievement_id',
'progress',
];
protected $casts = [
'progress' => 'integer',
];
// ---------------------------------------------------------------
// Relationships
// ---------------------------------------------------------------
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function achievement(): BelongsTo
{
return $this->belongsTo(Achievement::class);
}
}
+47
View File
@@ -0,0 +1,47 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class UserAction extends Model
{
protected $fillable = [
'user_id',
'type',
'data'
];
protected $casts = [
'user_id' => 'integer',
'data' => 'array',
];
protected $appends = [
'display_type',
];
protected function displayType(): Attribute
{
return Attribute::make(
get: fn () => match ($this->type) {
'flight_booked' => 'Flight Booked',
'flight_cancelled' => 'Flight Cancelled',
'flight_updated' => 'Flight Updated',
'flight_imported' => 'Flight Imported from FR24',
'flight_logged' => 'Flight Logged',
'flight_deleted' => 'Flight Deleted',
default => 'Unknown Action'
}
);
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
}
+221
View File
@@ -0,0 +1,221 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class UserFlight extends Model
{
protected $table = 'user_flights';
protected $fillable = [
'user_id',
'departure_date',
'arrival_date',
'flight_number',
'departure_airport_id',
'arrival_airport_id',
'airline_id',
'aircraft_id',
'aircraft_registration',
'seat_number',
'seat_type_id',
'flight_class_id',
'flight_reason_id',
'crew_type_id',
'note',
'auto_update',
];
protected $casts = [
'departure_date' => 'immutable_datetime',
'arrival_date' => 'immutable_datetime',
'auto_update' => 'boolean',
];
protected $appends = [
'departure_date_display',
'departure_time_display',
'arrival_date_display',
'arrival_time_display',
'arrival_day_difference',
'duration',
'duration_display',
'distance',
];
public function calculateGreatCircleDistance(): float{
$earthRadiusKm = 6371;
[$depLat, $depLong] = [$this->departureAirport->latitude_deg, $this->departureAirport->longitude_deg];
[$arrLat, $arrLong] = [$this->arrivalAirport->latitude_deg, $this->arrivalAirport->longitude_deg];
$latDelta = deg2rad($arrLat - $depLat);
$longDelta = deg2rad($arrLong - $depLong);
$a = sin($latDelta / 2) * sin($latDelta / 2)
+ cos(deg2rad($depLat)) * cos(deg2rad($arrLat))
* sin($longDelta / 2) * sin($longDelta / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
return $earthRadiusKm * $c;
}
protected function departureDateDisplay(): Attribute
{
return Attribute::make(
get: fn() => $this->departure_date
->toMutable()
->setTimezone($this->departureAirport->timezone)
->format('j M Y')
);
}
protected function departureTimeDisplay(): Attribute
{
return Attribute::make(
get: fn() => $this->departure_date
->toMutable()
->setTimezone($this->departureAirport->timezone)
->format('g:iA')
);
}
protected function arrivalDateDisplay(): Attribute
{
return Attribute::make(
get: fn() => $this->arrival_date
?->copy()
->setTimezone($this->arrivalAirport->timezone)
->format('j M Y')
);
}
protected function arrivalTimeDisplay(): Attribute
{
return Attribute::make(
get: fn() => $this->arrival_date
?->copy()
->setTimezone($this->arrivalAirport->timezone)
->format('g:iA')
);
}
protected function arrivalDayDifference(): Attribute
{
return Attribute::make(
get: function () {
if (!$this->arrival_date) return 0;
$departureLocal = $this->departure_date->copy()->setTimezone($this->departureAirport->timezone);
$arrivalLocal = $this->arrival_date->copy()->setTimezone($this->arrivalAirport->timezone);
return (int) abs(
Carbon::parse($arrivalLocal->toDateString())
->diffInDays(Carbon::parse($departureLocal->toDateString()))
);
}
);
}
protected function duration(): Attribute
{
return Attribute::make(
get: fn() => $this->departure_date->diffInMinutes($this->arrival_date)
);
}
protected function durationDisplay(): Attribute
{
return Attribute::make(
get: function () {
$hours = intdiv($this->duration, 60);
$minutes = $this->duration % 60;
return $hours . 'h ' . str_pad($minutes, 2, '0', STR_PAD_LEFT) . 'm';
}
);
}
protected function distance(): Attribute
{
return Attribute::make(
get: fn() => $this->calculateGreatCircleDistance()
);
}
public function isDomestic() : bool{
return $this->departureAirport->region->country_id == $this->arrivalAirport->region->country_id;
}
public function isInternational() : bool{
return !$this->isDomestic();
}
public static function snapshot($userFlightId){
return UserFlight::with([
'departureAirport',
'departureAirport.region.country',
'arrivalAirport',
'arrivalAirport.region.country',
'aircraft',
'airline',
'airline.country',
'airline.alliance',
'flightClass',
'seatType',
'flightReason',
'crewType',
])->find($userFlightId)->toArray();
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function departureAirport(): BelongsTo
{
return $this->belongsTo(Airport::class, 'departure_airport_id');
}
public function arrivalAirport(): BelongsTo
{
return $this->belongsTo(Airport::class, 'arrival_airport_id');
}
public function crewType(): BelongsTo
{
return $this->belongsTo(CrewType::class);
}
public function airline(): BelongsTo
{
return $this->belongsTo(Airline::class);
}
public function aircraft(): BelongsTo
{
return $this->belongsTo(Aircraft::class);
}
public function seatType(): BelongsTo
{
return $this->belongsTo(SeatType::class);
}
public function flightClass(): BelongsTo
{
return $this->belongsTo(FlightClass::class);
}
public function flightReason(): BelongsTo
{
return $this->belongsTo(FlightReason::class);
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Observers;
use App\Models\Achievement;
use App\Models\Airline;
use App\Models\Alliance;
class AirlineObserver
{
public function created(Airline $airline): void
{
if ($airline->alliance_id !== null) {
$this->syncAllianceThresholds();
}
}
public function updated(Airline $airline): void
{
if ($airline->wasChanged('alliance_id')) {
$this->syncAllianceThresholds();
}
}
public function deleted(Airline $airline): void
{
$this->syncAllianceThresholds();
}
private function syncAllianceThresholds(): void
{
Alliance::withCount('airlines')->each(function (Alliance $alliance) {
Achievement::where('internal_name', "airlines_alliances.all_{$alliance->internal_name}")
->update(['threshold' => $alliance->airlines_count]);
});
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
namespace App\Observers;
use App\Models\UserFlight;
class FlightObserver
{
/**
* Recalculate after a flight is created.
*/
public function created(UserFlight $flight): void
{
$flight->user->calculateAchievements();
}
/**
* Recalculate after a flight is updated.
* Cabin class, flight type, airline, etc. may have changed,
* which could unlock or revoke achievements.
*/
public function updated(UserFlight $flight): void
{
$flight->user->calculateAchievements();
}
/**
* Recalculate after a flight is deleted.
* Previously earned achievements may no longer be valid.
*/
public function deleted(UserFlight $flight): void
{
$flight->user->calculateAchievements();
}
}
+66
View File
@@ -0,0 +1,66 @@
<?php
namespace App\Policies;
use App\Models\Notification;
use App\Models\User;
use Illuminate\Auth\Access\Response;
class NotificationPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, Notification $notification): bool
{
return false;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return false;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Notification $notification): bool
{
return $user->id === $notification->user_id;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, Notification $notification): bool
{
return false;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, Notification $notification): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, Notification $notification): bool
{
return false;
}
}
+66
View File
@@ -0,0 +1,66 @@
<?php
namespace App\Policies;
use App\Models\User;
use App\Models\UserFlight;
use Illuminate\Auth\Access\Response;
class UserFlightPolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return false;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, UserFlight $userFlight): bool
{
return false;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return false;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, UserFlight $userFlight): bool
{
return $user->id === $userFlight->user_id;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, UserFlight $userFlight): bool
{
return $user->id === $userFlight->user_id;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, UserFlight $userFlight): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, UserFlight $userFlight): bool
{
return false;
}
}
+6
View File
@@ -2,6 +2,10 @@
namespace App\Providers;
use App\Models\Airline;
use App\Models\UserFlight;
use App\Observers\AirlineObserver;
use App\Observers\FlightObserver;
use Illuminate\Support\Facades\Vite;
use Illuminate\Support\ServiceProvider;
@@ -21,5 +25,7 @@ class AppServiceProvider extends ServiceProvider
public function boot(): void
{
Vite::prefetch(concurrency: 3);
UserFlight::observe(FlightObserver::class);
Airline::observe(AirlineObserver::class);
}
}
@@ -0,0 +1,163 @@
<?php
namespace App\Services\Achievements;
use App\Models\Achievement;
use App\Models\Notification;
use App\Models\User;
use App\Models\UserAchievement;
use App\Models\UserFlight;
use App\Services\Achievements\Checkers\AchievementCheckerInterface;
use App\Services\Achievements\Checkers\AircraftChecker;
use App\Services\Achievements\Checkers\CountriesAndContinentsChecker;
use App\Services\Achievements\Checkers\AirlinesAndAlliancesChecker;
use App\Services\Achievements\Checkers\FunChallengesChecker;
use App\Services\Achievements\Checkers\GeneralFlyingChecker;
use Illuminate\Support\Collection;
class AchievementService
{
/** Cached achievement lookups so checkers don't each hit the DB. */
private Collection $achievementCache;
/** The user currently being evaluated — set per calculate() call. */
private User $user;
private array $checkers = [
GeneralFlyingChecker::class,
CountriesAndContinentsChecker::class,
AircraftChecker::class,
AirlinesAndAlliancesChecker::class,
FunChallengesChecker::class,
];
public function __construct()
{
$this->achievementCache = collect();
}
// ---------------------------------------------------------------
// Orchestration
// ---------------------------------------------------------------
/**
* @var Collection<int,UserFlight> $flights
*/
private Collection $flights;
public function calculate(User $user): void
{
$this->user = $user;
$this->achievementCache = Achievement::all()->keyBy('internal_name');
// Load once with every relationship any checker could need
$this->flights = $user->flights()->with([
'airline.alliance',
'aircraft',
'flightClass',
'departureAirport.region',
'arrivalAirport.region',
'departureAirport.region.continent',
'arrivalAirport.region.continent',
])->get();
foreach ($this->checkers as $checkerClass) {
$checker = new $checkerClass($this);
$checker->check($user);
}
}
/**
* @return Collection<int,UserFlight>
*/
public function getFlights(): Collection
{
return $this->flights;
}
// ---------------------------------------------------------------
// Award / revoke
// ---------------------------------------------------------------
/**
* Upsert a user_achievement row and fire a notification if this
* is a newly unlocked achievement.
*/
public function award(Achievement $achievement, User $user, ?int $progress = null): void
{
$existing = UserAchievement::where('user_id', $user->id)
->where('achievement_id', $achievement->id)
->first();
$alreadyUnlocked = $existing !== null;
UserAchievement::updateOrCreate(
['user_id' => $user->id, 'achievement_id' => $achievement->id],
['progress' => $progress],
);
if (! $alreadyUnlocked) {
$this->createAchievementNotification($user, $achievement);
}
}
/**
* Update progress on a progressive achievement without marking it
* as unlocked (i.e. progress exists but threshold not yet met).
* Creates the row if it doesn't exist yet.
*/
public function updateProgress(Achievement $achievement, User $user, int $progress): void
{
UserAchievement::updateOrCreate(
['user_id' => $user->id, 'achievement_id' => $achievement->id],
['progress' => $progress],
);
}
/**
* Remove a user_achievement row and its associated notification
* if the achievement is no longer valid for this user.
*/
public function revoke(Achievement $achievement, User $user): void
{
UserAchievement::where('user_id', $user->id)
->where('achievement_id', $achievement->id)
->delete();
Notification::where('user_id', $user->id)
->where('achievement_id', $achievement->id)
->delete();
}
// ---------------------------------------------------------------
// Helpers for checkers
// ---------------------------------------------------------------
public function resolveAchievement(string $internalName): ?Achievement
{
$achievement = $this->achievementCache->get($internalName);
return $achievement instanceof Achievement ? $achievement : null;
}
public function currentUser(): User
{
return $this->user;
}
// ---------------------------------------------------------------
// Notifications
// ---------------------------------------------------------------
private function createAchievementNotification(User $user, Achievement $achievement): void
{
Notification::create([
'user_id' => $user->id,
'title' => $achievement->name,
'body' => $achievement->short_description,
'is_achievement' => true,
'achievement_id' => $achievement->id,
'expires_at' => null,
]);
}
}
@@ -0,0 +1,15 @@
<?php
namespace App\Services\Achievements\Checkers;
use App\Models\User;
interface AchievementCheckerInterface
{
/**
* Check all achievements in this category for the given user.
* Implementations should call $this->service->award() or $this->service->revoke()
* never touch user_achievements directly.
*/
public function check(): void;
}
@@ -0,0 +1,146 @@
<?php
namespace App\Services\Achievements\Checkers;
use App\Models\User;
use App\Models\UserFlight;
use Illuminate\Support\Collection;
class AircraftChecker extends BaseChecker
{
private const array BOEING_FAMILIES = [
'707' => ['B701', 'B703', 'B720'],
'717' => ['B712', 'B717'],
'727' => ['B721', 'B722', 'B727'],
'737' => ['B731', 'B732', 'B733', 'B734', 'B735', 'B736', 'B737', 'B738', 'B739', 'B37M', 'B38M', 'B39M'],
'747' => ['B741', 'B742', 'B743', 'B744', 'B748', 'B74D', 'B74R', 'B74S'],
'757' => ['B752', 'B753', 'B757'],
'767' => ['B762', 'B763', 'B764', 'B767'],
'777' => ['B772', 'B773', 'B77L', 'B77W', 'B778', 'B779'],
'787' => ['B788', 'B789', 'B78X'],
];
private const array AIRBUS_FAMILIES = [
'A300' => ['A30B', 'A300', 'A306'],
'A310' => ['A310', 'A312', 'A313'],
'A318' => ['A318'],
'A319' => ['A319', 'A31X'],
'A320' => ['A320', 'A20N'],
'A321' => ['A321', 'A21N'],
'A330' => ['A330', 'A332', 'A333', 'A338', 'A339'],
'A340' => ['A340', 'A342', 'A343', 'A345', 'A346'],
'A350' => ['A350', 'A358', 'A359', 'A35K'],
'A380' => ['A380', 'A388'],
];
private const array DOUBLE_DECKER_DESIGNATORS = [
// A380
'A380', 'A388',
// 747 variants
'B741', 'B742', 'B743', 'B744', 'B748', 'B74D', 'B74R', 'B74S',
];
public function check(): void
{
/**
* @var $flights Collection<int, UserFlight>
*/
$flights = $this->flights();
$flightsWithAircraft = $flights->filter(fn($f) => $f->aircraft !== null);
$this->awardIf(
$flightsWithAircraft->contains(
fn(UserFlight $f) => in_array($f->aircraft->aircraft_description, ['LandPlane', 'SeaPlane'])
),
'aircraft.fly_on_a_plane'
);
$this->awardIf(
$flightsWithAircraft->contains(
fn(UserFlight $f) => $f->aircraft->aircraft_description === 'Helicopter'
),
'aircraft.fly_on_a_helicopter'
);
$this->awardIf(
$flightsWithAircraft->contains(
fn(UserFlight $f) => $f->aircraft->engine_type === 'Jet'
),
'aircraft.fly_on_a_jet'
);
$this->awardIf(
$flightsWithAircraft->contains(
fn(UserFlight $f) => $f->aircraft->engine_type === 'Turboprop/Turboshaft' || $f->aircraft->engine_type === 'Piston'
),
'aircraft.fly_on_a_prop'
);
// --- Engine count achievements ---
$this->awardIf(
$flightsWithAircraft->contains(fn(UserFlight $f) => $f->aircraft->engine_count === 1 && $f->aircraft->aircraft_description !== 'Helicopter'),
'aircraft.single_engine'
);
$this->awardIf(
$flightsWithAircraft->contains(fn(UserFlight $f) => $f->aircraft->engine_count === 2 && $f->aircraft->aircraft_description !== 'Helicopter'),
'aircraft.twin_engine'
);
$this->awardIf(
$flightsWithAircraft->contains(fn(UserFlight $f) => $f->aircraft->engine_count === 3 && $f->aircraft->aircraft_description !== 'Helicopter'),
'aircraft.tri_engine'
);
$this->awardIf(
$flightsWithAircraft->contains(fn(UserFlight $f) => $f->aircraft->engine_count === 4 && $f->aircraft->aircraft_description !== 'Helicopter'),
'aircraft.quad_engine'
);
// --- Double decker ---
$this->awardIf(
$flightsWithAircraft->contains(
fn(UserFlight $f) => in_array($f->aircraft->designator, self::DOUBLE_DECKER_DESIGNATORS)
),
'aircraft.double_decker'
);
// --- Smaller manufacturer (scheduled service only) ---
$this->awardIf(
$flightsWithAircraft->contains(
fn(UserFlight $f) => $f->airline && $f->flight_number && !in_array(strtolower($f->aircraft->manufacturer_code), ['boeing', 'airbus'])
),
'aircraft.smaller_manufacturer'
);
// --- Boeing 7x7 families ---
$flownBoeingFamilies = collect(self::BOEING_FAMILIES)
->filter(fn($designators) =>
$flightsWithAircraft->contains(
fn(UserFlight $f) => in_array($f->aircraft->designator, $designators)
)
)
->count();
$this->awardProgress($flownBoeingFamilies, 'aircraft.all_boeing_7x7');
// --- Airbus A3xx families ---
$flownAirbusFamilie = collect(self::AIRBUS_FAMILIES)
->filter(fn($designators) =>
$flightsWithAircraft->contains(
fn(UserFlight $f) => in_array($f->aircraft->designator, $designators)
)
)
->count();
$this->awardProgress($flownAirbusFamilie, 'aircraft.all_airbus_a3xx');
}
}
@@ -0,0 +1,45 @@
<?php
namespace App\Services\Achievements\Checkers;
use App\Models\Alliance;
use App\Models\User;
use App\Models\UserFlight;
use Illuminate\Support\Collection;
class AirlinesAndAlliancesChecker extends BaseChecker
{
const array US_3 = ['american-airlines', 'delta', 'united-airlines'];
const array ME_3 = ['emirates', 'etihad-airways', 'qatar-airways'];
const array CN_3 = ['china-southern-airlines', 'china-eastern', 'air-china'];
public function check(): void
{
$flights = $this->flights();
$alliances = Alliance::withCount('airlines')->pluck('id', 'internal_name');
$flownAllianceAirlines = $flights
->filter(fn(UserFlight $f) => $f->airline?->alliance !== null)
->groupBy(fn(UserFlight $f) => $f->airline->alliance->internal_name)
->map(fn($group) => $group->pluck('airline.internal_name')->unique()->count());
$check = fn(string $alliance): int => $flownAllianceAirlines->get($alliance, 0);
$this->awardProgress($check('skyteam'), 'airlines_alliances.all_skyteam');
$this->awardProgress($check('oneworld'), 'airlines_alliances.all_oneworld');
$this->awardProgress($check('star_alliance'), 'airlines_alliances.all_star_alliance');
$this->awardProgress($check('vanilla_alliance'), 'airlines_alliances.all_vanilla_alliance');
$flownAirlines = $flights
->pluck('airline.internal_name')
->filter()
->unique();
$checkGroup = fn(array $group): int => $flownAirlines->intersect($group)->count();
$this->awardProgress($checkGroup(self::ME_3), 'airlines_alliances.me3');
$this->awardProgress($checkGroup(self::US_3), 'airlines_alliances.us3');
$this->awardProgress($checkGroup(self::CN_3), 'airlines_alliances.cn3');
}
}
@@ -0,0 +1,70 @@
<?php
namespace App\Services\Achievements\Checkers;
use App\Models\Achievement;
use App\Services\Achievements\AchievementService;
use Illuminate\Support\Collection;
abstract class BaseChecker implements AchievementCheckerInterface
{
public function __construct(protected AchievementService $service) {}
protected function flights(): Collection
{
return $this->service->getFlights();
}
/**
* Resolve an achievement ID from its internal name.
* Results are cached on the service so repeated lookups are free.
*/
protected function achievement(string $internalName): ?Achievement
{
return $this->service->resolveAchievement($internalName);
}
/**
* Award a boolean (non-progressive) achievement if the condition is met,
* or revoke it if the condition is no longer met.
*/
protected function awardIf(bool $condition, string $internalName): void
{
$achievement = $this->achievement($internalName);
if (! $achievement) {
return;
}
if ($condition) {
$this->service->award($achievement, $this->currentUser());
} else {
$this->service->revoke($achievement, $this->currentUser());
}
}
/**
* Award a progressive achievement, updating progress and
* unlocking/revoking based on whether progress meets the threshold.
*/
protected function awardProgress(int $progress, string $internalName): void
{
$achievement = $this->achievement($internalName);
if (! $achievement) return;
if ($progress >= $achievement->threshold) {
$this->service->award($achievement, $this->currentUser(), $progress);
} else {
$this->service->updateProgress($achievement, $this->currentUser(), $progress);
}
}
/**
* The user currently being evaluated.
* Set by AchievementService before calling check().
*/
protected function currentUser(): \App\Models\User
{
return $this->service->currentUser();
}
}
@@ -0,0 +1,97 @@
<?php
namespace App\Services\Achievements\Checkers;
use App\Models\Continent;
use App\Models\User;
use App\Models\UserFlight;
use Illuminate\Support\Collection;
class CountriesAndContinentsChecker extends BaseChecker
{
private const INHABITED_CONTINENTS = [
'africa', 'asia', 'europe', 'north_america', 'oceania', 'south_america',
];
public function check(): void
{
$flights = $this->flights();
// Resolve internal_name → id once, used throughout
$continents = Continent::pluck('id', 'internal_name');
$arrivalContinentIds = $flights->pluck('arrivalAirport.region.continent_id')->unique();
$has = fn(string $name) => $arrivalContinentIds->contains($continents[$name]);
// --- Simple "fly to X continent" achievements ---
$this->awardIf(
$flights->contains(fn(UserFlight $f) =>
$f->departureAirport->region->continent_id !== $f->arrivalAirport->region->continent_id
),
'countries_continents.intercontinental'
);
$this->awardIf($has('africa'), 'countries_continents.fly_to_africa');
$this->awardIf($has('asia'), 'countries_continents.fly_to_asia');
$this->awardIf($has('oceania'), 'countries_continents.fly_to_oceania');
$this->awardIf($has('antarctica'), 'countries_continents.fly_to_antarctica');
$this->awardIf($has('europe'), 'countries_continents.fly_to_europe');
$this->awardIf($has('south_america'), 'countries_continents.fly_to_south_america');
$this->awardIf($has('north_america'), 'countries_continents.fly_to_north_america');
// --- All inhabited continents ---
$inhabitedIds = collect(self::INHABITED_CONTINENTS)->map(fn($name) => $continents[$name]);
$visitedInhabited = $arrivalContinentIds
->intersect($inhabitedIds)
->unique()
->count();
$this->awardProgress($visitedInhabited, 'countries_continents.all_inhabited_continents');
// --- All continents including Antarctica ---
$this->awardProgress(
$arrivalContinentIds->unique()->count(),
'countries_continents.all_continents'
);
// --- Continent route pairs ---
$this->checkContinentPairs($flights);
}
/**
* @param Collection<int, UserFlight> $flights
* @return void
*/
private function checkContinentPairs(Collection $flights): void
{
$oneWayRoutes = collect();
$directedRoutes = collect();
foreach ($flights as $flight) {
$dep = $flight->departureAirport->region->continent->internal_name;
$arr = $flight->arrivalAirport->region->continent->internal_name;
// Directed route key e.g. "europe→asia"
$directedRoutes->push("{$dep}{$arr}");
// Undirected — sort alphabetically so "europe→asia" and "asia→europe" are the same
$undirected = implode('→', collect([$dep, $arr])->sort()->values()->all());
$oneWayRoutes->push($undirected);
}
$this->awardProgress(
$oneWayRoutes->unique()->count(),
'countries_continents.all_continent_pairs_one_way'
);
$this->awardProgress(
$directedRoutes->unique()->count(),
'countries_continents.all_continent_pairs_both_ways'
);
}
}
@@ -0,0 +1,135 @@
<?php
namespace App\Services\Achievements\Checkers;
use App\Models\User;
use App\Models\UserFlight;
class FunChallengesChecker extends BaseChecker
{
const array US_STATES = [
'US-AK', 'US-AL', 'US-AR', 'US-AZ', 'US-CA', 'US-CO', 'US-CT', 'US-DC',
'US-DE', 'US-FL', 'US-GA', 'US-HI', 'US-IA', 'US-ID', 'US-IL', 'US-IN',
'US-KS', 'US-KY', 'US-LA', 'US-MA', 'US-MD', 'US-ME', 'US-MI', 'US-MN',
'US-MO', 'US-MS', 'US-MT', 'US-NC', 'US-ND', 'US-NE', 'US-NH', 'US-NJ',
'US-NM', 'US-NV', 'US-NY', 'US-OH', 'US-OK', 'US-OR', 'US-PA', 'US-RI',
'US-SC', 'US-SD', 'US-TN', 'US-TX', 'US-UT', 'US-VA', 'US-VT', 'US-WA',
'US-WI', 'US-WV', 'US-WY',
];
const array AUSTRALIAN_STATES = [
'AU-ACT', 'AU-NSW', 'AU-NT', 'AU-QLD', 'AU-SA', 'AU-TAS', 'AU-VIC', 'AU-WA',
];
const array CHINESE_PROVINCES = [
'CN-11', 'CN-12', 'CN-13', 'CN-14', 'CN-15', 'CN-21', 'CN-22', 'CN-23',
'CN-31', 'CN-32', 'CN-33', 'CN-34', 'CN-35', 'CN-36', 'CN-37', 'CN-41',
'CN-42', 'CN-43', 'CN-44', 'CN-45', 'CN-46', 'CN-50', 'CN-51', 'CN-52',
'CN-53', 'CN-54', 'CN-61', 'CN-62', 'CN-63', 'CN-64', 'CN-65',
];
const array BRAZILIAN_STATES = [
'BR-AC', 'BR-AL', 'BR-AM', 'BR-AP', 'BR-BA', 'BR-CE', 'BR-DF', 'BR-ES',
'BR-GO', 'BR-MA', 'BR-MG', 'BR-MS', 'BR-MT', 'BR-PA', 'BR-PB', 'BR-PE',
'BR-PI', 'BR-PR', 'BR-RJ', 'BR-RN', 'BR-RO', 'BR-RR', 'BR-RS', 'BR-SC',
'BR-SE', 'BR-SP', 'BR-TO',
];
const array CANADIAN_PROVINCES = [
'CA-AB', 'CA-BC', 'CA-MB', 'CA-NB', 'CA-NL', 'CA-NS', 'CA-NT',
'CA-NU', 'CA-ON', 'CA-PE', 'CA-QC', 'CA-SK', 'CA-YT',
];
public function check(): void
{
$flights = $this->flights();
$airlineLetters = $flights
->filter(fn(UserFlight $f) => $f->airline?->IATA_code !== null)
->map(fn(UserFlight $f) => strtoupper($f->airline->IATA_code[0]))
->filter(fn($letter) => ctype_alpha($letter))
->unique()
->count();
$this->awardProgress($airlineLetters, 'fun_challenges.airline_alphabet');
$airportLetters = $flights
->flatMap(fn(UserFlight $f) => [
$f->departureAirport?->iata_code,
$f->arrivalAirport?->iata_code,
])
->filter()
->map(fn($code) => strtoupper($code[0]))
->unique()
->count();
$this->awardProgress($airportLetters, 'fun_challenges.airport_alphabet');
// --- US States ---
$visitedUsStates = $flights
->flatMap(fn(UserFlight $f) => [
$f->departureAirport?->region?->code,
$f->arrivalAirport?->region?->code,
])
->filter()
->filter(fn($code) => in_array($code, self::US_STATES))
->unique()
->count();
$this->awardProgress($visitedUsStates, 'fun_challenges.us_states');
// --- Australian States ---
$visitedAustralianStates = $flights
->flatMap(fn(UserFlight $f) => [
$f->departureAirport?->region?->code,
$f->arrivalAirport?->region?->code,
])
->filter()
->filter(fn($code) => in_array($code, self::AUSTRALIAN_STATES))
->unique()
->count();
$this->awardProgress($visitedAustralianStates, 'fun_challenges.australian_states');
// --- Chinese Provinces ---
$visitedChineseProvinces = $flights
->flatMap(fn(UserFlight $f) => [
$f->departureAirport?->region?->code,
$f->arrivalAirport?->region?->code,
])
->filter()
->filter(fn($code) => in_array($code, self::CHINESE_PROVINCES))
->unique()
->count();
$this->awardProgress($visitedChineseProvinces, 'fun_challenges.chinese_provinces');
// --- Brazilian States ---
$visitedBrazilianStates = $flights
->flatMap(fn(UserFlight $f) => [
$f->departureAirport?->region?->code,
$f->arrivalAirport?->region?->code,
])
->filter()
->filter(fn($code) => in_array($code, self::BRAZILIAN_STATES))
->unique()
->count();
$this->awardProgress($visitedBrazilianStates, 'fun_challenges.brazilian_states');
// --- Canadian Provinces ---
$visitedCanadianProvinces = $flights
->flatMap(fn(UserFlight $f) => [
$f->departureAirport?->region?->code,
$f->arrivalAirport?->region?->code,
])
->filter()
->filter(fn($code) => in_array($code, self::CANADIAN_PROVINCES))
->unique()
->count();
$this->awardProgress($visitedCanadianProvinces, 'fun_challenges.canadian_provinces');
}
}
@@ -0,0 +1,79 @@
<?php
namespace App\Services\Achievements\Checkers;
use App\Models\User;
use App\Models\UserFlight;
use Illuminate\Database\Eloquent\Collection;
class GeneralFlyingChecker extends BaseChecker
{
public function check(): void
{
/**
* @var $flights Collection<int, UserFlight>
*/
$flights = $this->flights();
$count = $flights->count();
// --- Boolean achievements ---
$this->awardIf($count >= 1, 'general_flying.first_flight');
$this->awardIf(
$flights->contains(fn ($f) => $f->isDomestic()),
'general_flying.domestic_flight'
);
$this->awardIf(
$flights->contains(fn ($f) => $f->isInternational()),
'general_flying.international_flight'
);
$this->awardIf(
$flights->contains(fn ($f) => $f->flightClass->internal_name === 'business'),
'general_flying.business_class'
);
$this->awardIf(
$flights->contains(fn ($f) => $f->flightClass->internal_name === 'first'),
'general_flying.first_class'
);
$this->awardIf(
$flights->contains(fn ($f) => $f->flightClass->internal_name === 'premium_economy'),
'general_flying.premium_economy'
);
$this->awardIf(
$flights->contains(fn ($f) => in_array($f->flightClass->internal_name, ['business', 'first'])),
'general_flying.business_or_first'
);
$this->awardIf(
$flights->contains(fn ($f) => $f->flightClass->internal_name === 'private'),
'general_flying.fly_private'
);
$this->awardIf(
$flights->contains(fn ($f) => $f->flightClass->internal_name === 'general_aviation'),
'general_flying.general_aviation'
);
$this->awardIf(
$flights->filter(fn (UserFlight $f) => $f->isDomestic())
->map(fn (UserFlight $f) => $f->departureAirport->region->country_id)
->unique()
->count() >= 2,
'general_flying.domestic_two_countries'
);
// --- Progressive achievements ---
$this->awardProgress($count,'general_flying.10_flights');
$this->awardProgress($count,'general_flying.50_flights');
$this->awardProgress($count,'general_flying.100_flights');
$this->awardProgress($count,'general_flying.500_flights');
$this->awardProgress($count,'general_flying.1000_flights');
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\Traits;
use App\Models\User;
use App\Services\Achievements\AchievementService;
/**
* @mixin User
*/
trait HasAchievements
{
public function calculateAchievements(): void
{
/** @var User $this */
app(AchievementService::class)->calculate($this);
}
}
+1
View File
@@ -7,6 +7,7 @@ use Illuminate\Foundation\Configuration\Middleware;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
+2 -1
View File
@@ -9,7 +9,8 @@
],
"license": "MIT",
"require": {
"php": "^8.3",
"php": "^8.4",
"ext-pdo": "*",
"inertiajs/inertia-laravel": "^2.0",
"laravel/framework": "^13.0",
"laravel/sanctum": "^4.0",
Generated
+3 -2
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "1378206c681cc15470824af157a889be",
"content-hash": "0e560320885031dd36bb08bb44fe05d4",
"packages": [
{
"name": "brick/math",
@@ -9369,7 +9369,8 @@
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^8.3"
"php": "^8.4",
"ext-pdo": "*"
},
"platform-dev": {},
"plugin-api-version": "2.9.0"
+2
View File
@@ -55,6 +55,8 @@ return [
'url' => env('APP_URL', 'http://localhost'),
'domain' => env('APP_DOMAIN', 'flightsgoneby.com'),
'api_domain' => env('API_DOMAIN', 'api.flightsgoneby.com'),
'logo_api_url' => env('LOGO_API_URL', 'https://api.flightsgoneby.com'),
'timezone_api_key' => env('TIMEZONE_API_KEY', '1234567890'),
/*
|--------------------------------------------------------------------------
| Application Timezone
+12
View File
@@ -99,6 +99,18 @@ return [
'sslmode' => env('DB_SSLMODE', 'prefer'),
],
'pgsql_production' => [
'driver' => 'pgsql',
'host' => env('PRODUCTION_DB_HOST', '127.0.0.1'),
'port' => env('PRODUCTION_DB_PORT', '5432'),
'database' => env('PRODUCTION_DB_DATABASE', ''),
'username' => env('PRODUCTION_DB_USERNAME', ''),
'password' => env('PRODUCTION_DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'url' => env('DB_URL'),
+84
View File
@@ -0,0 +1,84 @@
<?php
use Laravel\Sanctum\Sanctum;
return [
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
Sanctum::currentApplicationUrlWithPort(),
// Sanctum::currentRequestHost(),
))),
/*
|--------------------------------------------------------------------------
| Sanctum Guards
|--------------------------------------------------------------------------
|
| This array contains the authentication guards that will be checked when
| Sanctum is trying to authenticate a request. If none of these guards
| are able to authenticate the request, Sanctum will use the bearer
| token that's present on an incoming request for authentication.
|
*/
'guard' => ['web'],
/*
|--------------------------------------------------------------------------
| Expiration Minutes
|--------------------------------------------------------------------------
|
| This value controls the number of minutes until an issued token will be
| considered expired. This will override any values set in the token's
| "expires_at" attribute, but first-party sessions are not affected.
|
*/
'expiration' => null,
/*
|--------------------------------------------------------------------------
| Token Prefix
|--------------------------------------------------------------------------
|
| Sanctum can prefix new tokens in order to take advantage of numerous
| security scanning initiatives maintained by open source platforms
| that notify developers if they commit tokens into repositories.
|
| See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning
|
*/
'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''),
/*
|--------------------------------------------------------------------------
| Sanctum Middleware
|--------------------------------------------------------------------------
|
| When authenticating your first-party SPA with Sanctum you may need to
| customize some of the middleware Sanctum uses while processing the
| request. You may change the middleware listed below as required.
|
*/
'middleware' => [
'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class,
'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class,
'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class,
],
];
@@ -0,0 +1,128 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('airports', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->decimal('latitude_deg', 10, 6);
$table->decimal('longitude_deg', 10, 6);
$table->integer('elevation_ft')->nullable();
$table->foreignId('region_id')->constrained('regions');
$table->string('municipality')->nullable();
$table->string('icao_code')->nullable();
$table->string('iata_code')->nullable();
$table->string('local_code')->nullable();
$table->string('type');
$table->timestamps();
});
$this->importCsv();
}
public function down(): void
{
Schema::dropIfExists('airports');
}
private function importCsv(): void
{
$path = storage_path('app/private/seed_data/airports.csv');
if (! file_exists($path)) {
throw new \RuntimeException("Airports CSV not found at: {$path}");
}
$handle = fopen($path, 'rb');
if ($handle === false) {
throw new \RuntimeException("Failed to open airports CSV at: {$path}");
}
// Skip header row
fgetcsv($handle);
$regionMap = DB::table('regions')->pluck('id', 'code')->all();
$batch = [];
$batchSize = 500;
$now = now()->toDateTimeString();
while (($row = fgetcsv($handle)) !== false) {
if (count($row) < 19) {
continue;
}
// id, ident, type, name, latitude_deg, longitude_deg, elevation_ft,
// continent, iso_country, iso_region, municipality, scheduled_service,
// icao_code, iata_code, gps_code, local_code, home_link, wikipedia_link, keywords
[
,
,
$type,
$name,
$latitudeDeg,
$longitudeDeg,
$elevationFt,
,
,
$isoRegion,
$municipality,
,
$icaoCode,
$iataCode,
,
$localCode,
] = $row;
$icaoCode = trim(str_replace(["\r", "\n"], '', $icaoCode));
$iataCode = trim(str_replace(["\r", "\n"], '', $iataCode));
// Skip rows without at least one of iata or icao
if ($icaoCode === '' && $iataCode === '') {
continue;
}
$isoRegion = trim($isoRegion);
if (! isset($regionMap[$isoRegion])) {
continue;
}
$elevationFt = trim($elevationFt);
$batch[] = [
'type' => trim($type),
'name' => trim($name),
'latitude_deg' => (float) trim($latitudeDeg),
'longitude_deg' => (float) trim($longitudeDeg),
'elevation_ft' => $elevationFt !== '' ? (int) $elevationFt : null,
'region_id' => $regionMap[$isoRegion],
'municipality' => trim($municipality) !== '' ? trim($municipality) : null,
'icao_code' => $icaoCode !== '' ? $icaoCode : null,
'iata_code' => $iataCode !== '' ? $iataCode : null,
'local_code' => trim($localCode) !== '' ? trim($localCode) : null,
'created_at' => $now,
'updated_at' => $now,
];
if (count($batch) >= $batchSize) {
DB::table('airports')->insert($batch);
$batch = [];
}
}
fclose($handle);
if (! empty($batch)) {
DB::table('airports')->insert($batch);
}
}
};
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
private string $icaoCode = 'YSWS';
public function up(): void
{
$region = DB::table('regions')->where('code', 'AU-NSW')->firstOrFail();
DB::table('airports')->insert([
'type' => 'large_airport', // large_airport, medium_airport, small_airport, heliport, seaplane_base, balloonport, closed
'name' => 'Western Sydney International Airport',
'latitude_deg' => -33.883461,
'longitude_deg'=> 150.712981,
'elevation_ft' => 262,
'region_id' => $region->id,
'municipality' => 'Sydney',
'icao_code' => $this->icaoCode,
'iata_code' => 'WSI',
'local_code' => null,
'created_at' => now(),
'updated_at' => now(),
]);
}
public function down(): void
{
DB::table('airports')->where('icao_code', $this->icaoCode)->delete();
}
};
@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('imported_flights', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('date')->nullable();
$table->string('flight_number')->nullable();
$table->string('from')->nullable();
$table->string('to')->nullable();
$table->string('dep_time')->nullable();
$table->string('arr_time')->nullable();
$table->string('duration')->nullable();
$table->string('airline')->nullable();
$table->string('aircraft')->nullable();
$table->string('registration')->nullable();
$table->string('seat_number')->nullable();
$table->string('seat_type')->nullable();
$table->string('flight_class')->nullable();
$table->string('flight_reason')->nullable();
$table->text('note')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('imported_flights');
}
};
@@ -0,0 +1,22 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('airports', function (Blueprint $table) {
$table->string('timezone')->nullable()->after('elevation_ft');
});
}
public function down(): void
{
Schema::table('airports', function (Blueprint $table) {
$table->dropColumn('timezone');
});
}
};
@@ -0,0 +1,58 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('flight_classes', function (Blueprint $table) {
$table->unsignedTinyInteger('id')->primary();
$table->string('name');
});
Schema::create('seat_types', function (Blueprint $table) {
$table->unsignedTinyInteger('id')->primary();
$table->string('name');
});
Schema::create('flight_reasons', function (Blueprint $table) {
$table->unsignedTinyInteger('id')->primary();
$table->string('name');
});
DB::table('flight_classes')->insert([
['id' => 0, 'name' => 'Unspecified'],
['id' => 1, 'name' => 'Economy'],
['id' => 2, 'name' => 'Business'],
['id' => 3, 'name' => 'First'],
['id' => 4, 'name' => 'Premium Economy'],
['id' => 5, 'name' => 'Private'],
]);
DB::table('seat_types')->insert([
['id' => 0, 'name' => 'Unspecified'],
['id' => 1, 'name' => 'Window'],
['id' => 2, 'name' => 'Middle'],
['id' => 3, 'name' => 'Aisle'],
]);
DB::table('flight_reasons')->insert([
['id' => 0, 'name' => 'No Particular Reason'],
['id' => 1, 'name' => 'Pleasure'],
['id' => 2, 'name' => 'Business'],
['id' => 3, 'name' => 'Crew'],
['id' => 4, 'name' => 'Other'],
]);
}
public function down(): void
{
Schema::dropIfExists('flight_reasons');
Schema::dropIfExists('seat_types');
Schema::dropIfExists('flight_classes');
}
};
@@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('user_flights', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->timestampTz('departure_date');
$table->timestampTz('arrival_date');
$table->string('flight_number')->nullable();
$table->foreignId('departure_airport_id')->constrained('airports');
$table->foreignId('arrival_airport_id')->constrained('airports');
$table->foreignId('airline_id')->nullable()->constrained('airlines');
$table->foreignId('aircraft_id')->nullable()->constrained('aircraft');
$table->string('aircraft_registration')->nullable();
$table->string('seat_number')->nullable();
$table->unsignedTinyInteger('seat_type_id')->nullable();
$table->unsignedTinyInteger('flight_reason_id')->nullable();
$table->unsignedTinyInteger('flight_class_id')->nullable();
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('seat_type_id')->references('id')->on('seat_types');
$table->foreign('flight_reason_id')->references('id')->on('flight_reasons');
$table->foreign('flight_class_id')->references('id')->on('flight_classes');
});
}
public function down(): void
{
Schema::dropIfExists('user_flights');
}
};
@@ -0,0 +1,80 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
private array $countryCodes = [
'Burma' => 'MM', // Myanmar
'Ceylon' => 'LK', // Sri Lanka
'congodr' => 'CD', // Congo, Dem. Republic
'cotedivoire' => 'CI', // Côte d'Ivoire
'dominicanrep' => 'DO', // Dominican Republic
'Kenya, Uganda and Tanzania' => 'KE', // East African Airways — headquartered in Nairobi
'Korea, Republic of' => 'KR', // South Korea
'Malaysia / Singapore' => 'MY', // Malaysia-Singapore Airlines predecessor
'Rhodesia' => 'ZW', // Zimbabwe
'Saudia Arabia' => 'SA', // Typo for Saudi Arabia
'St. Barthelemy' => 'BL', // Saint Barthélemy
'St. Martin' => 'MF', // Saint Martin (French side — change to SX for Dutch)
'Tanzania, United Republic of' => 'TZ',
'uae' => 'AE', // United Arab Emirates
'United States of America' => 'US',
'West Samoa' => 'WS', // Samoa
];
public function up(): void
{
// 1. Insert Lufthansa
DB::table('airlines')->insert([
'IATA_code' => 'LH',
'ICAO_code' => 'DLH',
'name' => 'Lufthansa',
'internal_name' => 'lufthansa',
'country_code' => 'DE',
'country_name' => 'Germany',
'active' => true,
'logo' => 'LH.png',
]);
// 2. Add nullable country_id FK column
Schema::table('airlines', function (Blueprint $table) {
$table->foreignId('country_id')
->nullable()
->after('active')
->constrained('countries', 'id')
->onUpdate('cascade')
->onDelete('set null');
});
foreach ($this->countryCodes as $countryName => $isoCode) {
DB::statement("
UPDATE airlines a
SET country_id = c.id
FROM countries c
WHERE c.code = :code
AND a.country_name = :name
AND a.country_id IS NULL
", [
'code' => $isoCode,
'name' => $countryName,
]);
}
}
public function down(): void
{
// Remove the FK column
Schema::table('airlines', function (Blueprint $table) {
$table->dropConstrainedForeignId('country_id');
});
// Remove Lufthansa (identified by unique ICAO code)
DB::table('airlines')->where('ICAO_code', 'DLH')->delete();
}
};
@@ -0,0 +1,748 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Each entry: id => ISO 3166-1 alpha-2 country code.
* '??' means the country could not be determined with confidence.
*
* Logic used:
* - Known airline name country from public record
* - ICAO callsign prefix (where visible in data)
* - Organisation/government name (e.g. "Belgian Air Force" BE)
* - "Blocked" placeholder rows left as ?? (no real airline)
*/
private array $map = [
// ── A ──────────────────────────────────────────────────────────────
1014 => '??', // Eastwest Airlines — multiple airlines use this name (AU/PH)
1359 => '??', // ADV — no name, no data
1383 => 'FR', // HOP!-AIRLINAIR — French regional carrier
1388 => 'IT', // Air One Aviation — Italy
1403 => 'VE', // Rutas Aereas de Venezuela RAV S.A — Venezuela
1416 => 'BT', // Tashi Air — Bhutan
1451 => 'CA', // Hawkair Aviation — Canada (BC)
1473 => '??', // Air Inter Transport Co. Ltd. — unclear
1507 => 'AR', // Tectimes Sudamericana S.A. — Argentina
1510 => 'HR', // Trade Air Ltd. — Croatia
1518 => 'US', // Conquest Air, Inc. — USA
1524 => 'GB', // CHEP Aerospace Solutions Ltd. — UK
1529 => 'LK', // Saffron Aviation (Pvt) Ltd dba Cinn Air — Sri Lanka
1569 => 'CY', // Cobaltair Ltd — Cyprus
1578 => 'TZ', // Coastal Travels Ltd. — Tanzania
1581 => 'GB', // UBM Aviation - OAG — UK
1632 => 'NO', // Norwegian Air Norway AS — Norway
1654 => 'NG', // Dornier Aviation Nigeria AIEP Limit — Nigeria
1658 => 'GB', // Air Direct Connect Ltd. — UK
1676 => 'DO', // Dominican Wings. S.A. — Dominican Republic
1691 => 'AT', // Eurowings Europe GmbH — Austria
1696 => 'LA', // Sabaidee Airways dba New Gen — Laos
1704 => 'CG', // Equaflight Service — Republic of Congo
1749 => 'NL', // European Cargo Services BV — Netherlands
1852 => 'NL', // Airshop B.V. — Netherlands
1871 => '??', // S.A.C. — insufficient info
1911 => 'GN', // Guinea Lineas Aereas — Guinea
1935 => 'US', // Global Feeder Services, LLC — USA
1951 => 'US', // Sky Lease I, Inc. — USA
2023 => 'CA', // Harbour Air — Canada
2029 => 'RU', // iFly Airlines — Russia
2031 => 'HT', // Haiti Aviation — Haiti
2035 => 'AM', // Taron Avia LLC — Armenia
2041 => 'CL', // Chilejet S.A. — Chile
2096 => 'SE', // Amapola Flyg AB — Sweden
2137 => 'CI', // Ivoirienne de Transport Aerien — Côte d'Ivoire
2159 => '??', // Airmax Airlines — unclear
2171 => 'RU', // Sapsan Air / Irtysh Air — Russia
2192 => 'US', // Intercontinental Airways (USA) — USA
2200 => 'FR', // Michelin Air Services — France
2219 => 'KH', // Apsara International — Cambodia
2283 => 'JP', // Japan Air Commuter Co., Ltd. — Japan
2327 => 'DK', // Jet Time A/S — Denmark
2351 => 'KE', // DAC Aviation (EC) Ltd. — Kenya
2353 => '??', // Skybus (KAL Aviation) — unclear
2361 => 'ID', // Jatayu Air — Indonesia
2491 => 'US', // American Capital Aviation — USA
2494 => 'US', // Aviation Services & Support — USA
2497 => 'VE', // Linea Aerea SAPSA — Venezuela
2510 => 'US', // Bristow U.S. LLC — USA
2525 => 'TZ', // Lion Air Cargo Tanzania Limited — Tanzania
2527 => 'GY', // Laparkan Airways — Guyana
2574 => 'US', // Pacific Wings — USA (Hawaii)
2579 => 'CH', // Swiss Global Air Lines AG — Switzerland
2583 => 'DE', // MHS Aviation GmbH — Germany
2598 => 'PH', // Magnum Air dba Skyjet — Philippines
2638 => 'US', // Mohawk Airlines — USA (historical)
2648 => '??', // Mey-Air — insufficient info
2680 => 'LB', // TMA Cargo — Lebanon (Trans Mediterranean Airways)
2691 => 'ZA', // Nomad Aviation (PTY) Ltd. — South Africa
2692 => 'FI', // Nordic Regional Airlines Oy — Finland
2704 => 'NG', // Skypower Express Airways Ltd. — Nigeria
2856 => 'AU', // FlyPelican — Australia
2896 => 'PL', // Small Planet Airline Sp. Z.o.o — Poland
2898 => 'PL', // Sprintair SA — Poland
2929 => 'IN', // Vayudoot — India (historical)
2947 => 'BS', // Southern Air Charter — Bahamas
2965 => 'PH', // AirAsia Inc. — Philippines
2989 => 'AI', // Anguilla Air Services, Ltd — Anguilla
3019 => 'RU', // Dobrolet — Russia
3033 => 'US', // Jet Airways Inc. — USA
3038 => 'VE', // Linea Aerea De Servicio Ejecutivo Regional Laser — Venezuela
3051 => '??', // Starlight Airline — insufficient info
3055 => 'US', // North Eastern International — USA
3057 => 'CZ', // SmartWings — Czech Republic
3062 => 'CO', // Tampa Cargo S.A.S — Colombia
3084 => '??', // Reliable Unique Services Aviation — insufficient info
3094 => 'VE', // Sundance Air Venezuela S.A. — Venezuela
3127 => '??', // Skyview Airways Company Limited — insufficient info
3167 => 'CA', // 8165343 Canada Inc. dba Air Canada — Canada
3187 => 'CR', // SANSA Regional — Costa Rica
3191 => 'CR', // Servicios Aereos Nacionales S.A. SANSA — Costa Rica
3198 => 'US', // Metro Air Northeast — USA
3199 => 'US', // Brockway Air — USA
3251 => 'TH', // Thai Lion Mentari Co., Ltd. — Thailand
3257 => '??', // Sunshine Airlines — insufficient info
3261 => 'TH', // Apex Airline Public Company Limited — Thailand
3289 => 'GB', // AirTanker Services Limited — UK
3291 => '??', // Fly Art — insufficient info
3292 => 'CA', // Nakina Air Service — Canada (Ontario)
3307 => 'MX', // MCS Aerocarga de Mexico — Mexico
3317 => '??', // Master Aviation — insufficient info
3358 => '??', // Jet 24 — insufficient info
3458 => 'US', // Empire Airlines (1975) — USA
3486 => 'VE', // Vensecar Internacional C.A. — Venezuela
3499 => '??', // Clairmont Holdings dba VI Air — insufficient info
3514 => '??', // Flylink Express — insufficient info
3533 => 'IT', // CAI Second — Italy
3564 => 'FR', // Air Vendee — France
3576 => 'US', // Vintage Props & Jets — USA
3638 => 'US', // Centurion Air Cargo, Inc. — USA
3687 => 'US', // Midwest Airlines — USA
3690 => 'PT', // Aero VIP Companhia Transportes Servicos Aere — Portugal
3691 => 'US', // Midwest Airlines (duplicate) — USA
3705 => 'RU', // Closed Joint Stock Company Red Wing — Russia
3713 => 'US', // Air Excursion, LLC — USA
3722 => 'US', // Exec Air, Inc. of Naples — USA (Florida)
3726 => 'CL', // Airmax S.A. — Chile
3732 => 'CA', // IATA - Montreal — Canada
3737 => 'US', // Universal Air Travel Plan (UATP-Marketing) — USA
3743 => 'US', // Delux Public Charter LLC — USA
3763 => 'ID', // Xpressair — Indonesia
3769 => 'US', // TEM Enterprises — USA
3775 => 'ID', // Indonesia AirAsia Extra, PT — Indonesia
3797 => 'CH', // Travel Technology Interactive SA — Switzerland
3831 => 'CA', // Department of National Defence — Canada
3832 => 'CN', // YTO Cargo Airlines Co. Ltd. — China
3837 => 'CN', // Yunnan Ying'An Airlines — China
3843 => 'CN', // Yunnan Yingan Airline Co., Ltd. — China
3857 => 'MX', // Link Conexion Aerea S.A. de C.V — Mexico
3878 => 'US', // PM Air LLC — USA
3914 => 'US', // Air Routing International L.P. — USA
3952 => 'RU', // Bashkortavia — Russia
3953 => '??', // Sun Air — insufficient info (multiple carriers)
// ── ICAO-only rows (no IATA code) ──────────────────────────────────
4197 => 'BE', // Abelag Aviation — Belgium
4206 => 'UA', // Alpha Air (Ukraine) — Ukraine
4208 => 'US', // Air Aurora — USA
4235 => '??', // Aeolus Air — insufficient info
4270 => 'CA', // Exploits Valley Air Services — Canada (Newfoundland)
4295 => 'US', // Nantucket Airlines — USA
4303 => 'MX', // Aero Comondu — Mexico
4309 => '??', // ASSL — insufficient info
4313 => 'US', // Flight Line — USA
4322 => '??', // Blocked
4327 => 'UA', // Antonov Airlines — Ukraine
4344 => 'DE', // Aero Dienst — Germany
4368 => 'EE', // Airest — Estonia
4377 => '??', // AEROTEC — insufficient info
4413 => '??', // Blocked
4443 => 'AO', // Angola Air Charter — Angola
4460 => 'AZ', // AZAL Avia Cargo — Azerbaijan
4488 => 'FR', // Airbus Industrie — France (Toulouse HQ)
4504 => 'RU', // AIS Airlines (Russia) — Russia
4569 => '??', // International Association Of Latin American Air Carriers — regional body
4572 => 'US', // American Linehaul Corporation — USA
4627 => '??', // Aerom — insufficient info
4639 => 'BR', // ASTA Linhas Aereas — Brazil
4646 => '??', // Amiyi Airlines — insufficient info
4663 => 'DE', // Antares Airtransport — Germany
4678 => 'GB', // OAG Computer — UK
4681 => '??', // Aerolion International — insufficient info
4705 => 'US', // Aeros Flight Training — USA
4780 => 'ZA', // Aeronexus — South Africa
4846 => 'AU', // Royal Australian Air Force — Australia
4862 => 'AU', // Par Avion Airlines — Australia (Tasmania)
4880 => 'DE', // Avanti Air GmbH — Germany
4966 => 'NZ', // Airwork (NZ) — New Zealand
4970 => 'NE', // Air Niamey S.A. — Niger
4976 => 'JO', // Arab Wings — Jordan
5040 => 'RU', // Azov-Avia — Russia
5054 => 'GB', // BAe Systems — UK
5057 => 'BE', // Belgian Air Force — Belgium
5082 => 'UA', // Bravo Airways — Ukraine
5095 => 'KZ', // Beibars — Kazakhstan
5123 => 'DK', // BenAir — Denmark
5127 => 'GB', // QinetiQ — UK
5148 => '??', // Airnow — insufficient info
5161 => 'IN', // Kingfisher Air Service — India
5178 => '??', // BFS International — insufficient info
5197 => '??', // Air Inter Transport — insufficient info
5203 => 'NO', // Bergen Air Transport — Norway
5214 => 'GB', // Bristow Helicopters — UK
5227 => 'DE', // BinAir — Germany
5339 => '??', // Sundance Air — insufficient info
5347 => 'CA', // Alberni Airways — Canada (BC)
5377 => 'ID', // Merpati Intan — Indonesia
5389 => 'HU', // Base Kft — Hungary
5401 => 'AU', // Star Air Cargo Pty — Australia
5418 => 'RU', // AeroBratsk JSC — Russia
5485 => '??', // Blocked
5534 => '??', // Blocked
5552 => '??', // Blocked
5569 => '??', // Blocked
5629 => 'CN', // Air China Cargo — China
5648 => '??', // Blocked
5683 => 'US', // Chipola Aviation — USA (Florida)
5694 => 'CN', // China Flying Dragon Aviation — China
5716 => 'MX', // Aereo Calafia — Mexico
5718 => 'CN', // Zhongfei Airlines — China
5723 => 'US', // Charlotte NC Air National Guard — USA
5751 => 'CA', // Cougar Helicopters — Canada
5758 => 'US', // Channel Islands Aviation — USA (California)
5813 => 'NG', // Caverton Helicopters Ltd. — Nigeria
5821 => 'US', // Aviation Charter Services — USA
5839 => 'US', // Colemill Air Charter — USA
5844 => 'GB', // Cello Aviation — UK
5859 => '??', // Challenge Air — insufficient info
5916 => 'CA', // Sunwest Aviation — Canada
5956 => 'US', // ConocoPhillips — USA
5959 => '??', // Blocked
5983 => 'US', // Corpjet — USA
5996 => 'US', // Corporate Air — USA
6043 => '??', // Avia Carriers — insufficient info
6075 => 'US', // Aero Charter and Transport — USA
6084 => '??', // CTI - Container Transport International — insufficient info
6093 => 'UZ', // Tashkent Aircraft Production — Uzbekistan
6102 => 'BR', // PanAir Cargo — Brazil
6106 => 'AR', // CATA Linea Aerea — Argentina
6113 => 'MX', // Aero Cuahonte — Mexico
6116 => 'ZA', // Court Helicopters — South Africa
6132 => 'US', // ChevronTexaco Aircraft Operations — USA
6146 => 'MH', // Air Marshall Islands — Marshall Islands
6179 => '??', // Blocked
6180 => '??', // Blocked
6181 => '??', // Blocked
6182 => '??', // Blocked
6183 => '??', // Blocked
6184 => '??', // Blocked
6185 => '??', // Blocked
6186 => '??', // Blocked
6187 => '??', // Blocked
6188 => '??', // Blocked
6189 => '??', // Blocked
6190 => '??', // Blocked
6191 => '??', // Blocked
6192 => '??', // Blocked
6193 => '??', // Blocked
6194 => '??', // Blocked
6195 => '??', // Blocked
6196 => '??', // Blocked
6197 => '??', // Blocked
6198 => '??', // Blocked
6199 => '??', // Blocked
6200 => '??', // Blocked
6201 => '??', // Blocked
6202 => '??', // Blocked
6203 => '??', // Blocked
6204 => '??', // Blocked
6222 => 'NG', // Dornier Aviation Nigeria — Nigeria
6250 => 'DE', // DC Aviation — Germany
6253 => 'GB', // Directflight Limited — UK
6257 => 'US', // Pentastar Aviation — USA
6259 => '??', // Blocked
6294 => '??', // Dasnair — insufficient info
6320 => 'US', // Encore Air Cargo — USA
6355 => '??', // Blocked
6377 => '??', // Blocked
6429 => 'AE', // Dubai Air Wing — UAE
6431 => '??', // Aerotecnica — insufficient info
6442 => 'AW', // Divi Divi Air N.V. — Aruba
6455 => '??', // Blocked
6463 => 'NZ', // Eagle Airways — New Zealand
6475 => 'AU', // Eastern Australia Airlines — Australia
6522 => '??', // Blocked
6539 => '??', // Blocked
6549 => 'AT', // Avanti Airlines — Austria
6570 => '??', // Excellent Glide — insufficient info
6601 => 'US', // Executive Jet Management — USA
6665 => '??', // Blocked
6691 => 'SI', // Express Airways d.o.o — Slovenia
6694 => 'US', // Epps Air Service — USA
6702 => 'MX', // Aerotaxis Tucan — Mexico
6787 => 'DE', // EFS European Flight Service — Germany
6790 => 'IT', // Evin-Evoluzionhndustriali — Italy
6791 => 'BR', // Everjets Aviacao Executiva S.A. — Brazil
6804 => 'AT', // Eurowings Europe — Austria
6827 => '??', // Blocked
6833 => 'DE', // Nightexpress — Germany
6839 => '??', // Elytra Charter — insufficient info
6847 => '??', // Blocked
6859 => 'HU', // ASL Airlines Hungary — Hungary
6865 => 'SE', // Falcon Air — Sweden
6913 => 'FR', // SEFA — France
6920 => 'AU', // Nav Air Charter — Australia
6923 => '??', // Blocked
6985 => 'RU', // Test Flight Aerographical Center — Russia
7013 => 'US', // CitationAir — USA
7024 => 'ZW', // Fastjet Zimbabwe — Zimbabwe
7042 => 'ES', // Prestige Jet Spain — Spain
7064 => 'US', // Flight Express — USA
7065 => 'RU', // I-Fly — Russia
7078 => 'IS', // Norlandair — Iceland
7092 => '??', // Blocked
7133 => 'US', // Freight Runners Express — USA
7142 => 'NG', // FirstNation Airways — Nigeria
7150 => 'US', // Farwest Airlines — USA
7233 => '??', // Foxair — insufficient info
7244 => 'BE', // Flying Service — Belgium
7248 => '??', // Comfort Air — insufficient info
7253 => 'BR', // Flyways Linhas Aereas — Brazil
7255 => '??', // Blocked
7268 => 'DE', // Luftwaffe — Germany
7271 => 'RU', // Gromov Air — Russia
7274 => 'VE', // Alianza Glancelot C.A. — Venezuela
7329 => '??', // Blocked
7421 => 'LY', // Ghadames Air — Libya
7425 => 'DE', // German Sky Airlines — Germany
7460 => '??', // Grivco International — insufficient info
7479 => '??', // Tranzglobal — insufficient info
7492 => '??', // Gloria — insufficient info
7496 => '??', // General Corporation For Light Air Transport — insufficient info
7502 => 'GB', // Gama Aviation — UK
7514 => 'MX', // Magnicharters — Mexico
7525 => '??', // Blocked
7531 => '??', // Genex — insufficient info
7551 => '??', // Waltair Europe — insufficient info
7552 => '??', // Blocked
7572 => 'BR', // Agroar Carga Aerea — Brazil
7627 => '??', // An-2 — insufficient info
7654 => '??', // Blocked
7655 => 'RU', // V. Grizodubova Air Company — Russia
7717 => '??', // Blocked
7722 => '??', // Blocked
7749 => 'GB', // Highland European — UK (Scotland)
7802 => 'US', // Superior Aviation — USA
7809 => 'US', // Hawkaire — USA
7813 => 'NO', // CHC Helikopter Service — Norway
7824 => 'FR', // Heli Securite — France
7863 => '??', // Blocked
7903 => '??', // Helistar — insufficient info
7944 => 'US', // Grossman Air Service — USA
7993 => 'RU', // Private Sky — Russia
7995 => '??', // Blocked
8036 => 'ES', // Ibertrans Aerea — Spain
8050 => 'CA', // Kalair — Canada
8053 => 'CA', // ICAO — Canada (Montreal HQ)
8066 => '??', // Blocked
8091 => 'US', // IFL Group — USA
8096 => 'DE', // Interflight — Germany
8125 => 'US', // InterJet West — USA
8148 => 'RU', // Ilavia — Russia
8180 => 'GR', // InterJet Hellenic — Greece
8223 => '??', // Blocked
8226 => 'US', // CSA Air — USA
8240 => 'IR', // Eram Air — Iran
8294 => '??', // Chavia — insufficient info
8295 => '??', // Blocked
8296 => 'IR', // Zagros Airlines — Iran
8302 => 'AT', // Jetalliance Flugbetriebs — Austria
8320 => 'CN', // Sino Jet (Beijing) — China
8326 => 'US', // Jetcraft Aviation — USA
8339 => '??', // Blocked
8353 => 'FI', // Jetflite — Finland
8363 => '??', // JS Aviation — insufficient info
8368 => 'JP', // JAL Express — Japan
8440 => '??', // Blocked
8445 => 'US', // Journey Aviation — USA
8451 => 'SE', // Jonair Affarsflyg AB — Sweden
8503 => 'FI', // Jet Time Finland — Finland
8544 => '??', // Blocked
8570 => 'GM', // Gamair — Gambia
8584 => '??', // Blocked
8586 => 'US', // Makani Kai Air — USA (Hawaii)
8614 => 'EG', // Alexandria Airlines — Egypt
8617 => 'UA', // Aircompany KHORS — Ukraine
8673 => '??', // Blocked
8707 => 'NZ', // Kiwi Regional Airlines — New Zealand
8725 => 'RU', // Kosmos Airlines — Russia
8732 => '??', // UN Humanitarian Relief Flights (Kosovo) — international
8737 => 'LT', // TransAviaBaltika — Lithuania
8744 => 'RU', // Kotlas Air — Russia
8784 => '??', // Blocked
8788 => 'KZ', // Zhezair — Kazakhstan
8810 => 'CO', // Lineas Aereas Suramericanas — Colombia
8826 => 'US', // Quest Diagnostics — USA
8846 => 'MX', // TAR Aerolineas — Mexico
8850 => '??', // Blocked
8883 => 'MX', // Aerolineas Ejecutivas — Mexico
8933 => 'SI', // Limitless Airways d.o.o — Slovenia
8948 => 'RU', // Luk Aero — Russia
8988 => 'DE', // Small Planet Airlines Germany — Germany
8990 => '??', // Let's Fly — insufficient info
9018 => '??', // Blocked
9020 => '??', // Links Air — insufficient info
9027 => 'GB', // London Executive Aviation — UK
9068 => 'RU', // Alrosa-Avia — Russia
9080 => '??', // Airailes — insufficient info
9146 => 'LU', // Luxaviation S.A. — Luxembourg
9151 => 'US', // Flexjet — USA
9158 => 'GB', // LyddAir — UK
9168 => '??', // Blocked
9186 => 'CA', // Morningstar Air Express — Canada
9199 => 'GR', // Minoan Air S.A. — Greece
9202 => '??', // Max Aviation — insufficient info
9251 => '??', // Blocked
9268 => '??', // Shervbery — insufficient info
9290 => 'GB', // Merlin Airways — UK
9301 => 'RO', // ICAR — Romania
9365 => '??', // Blocked
9386 => '??', // Air Majoro — insufficient info
9403 => 'TW', // Makung Airlines — Taiwan
9428 => 'MT', // Maleth Aero — Malta
9472 => 'IT', // MiniLiner s.r.l. — Italy
9474 => '??', // Blocked
9553 => 'CN', // Minsheng International Jet — China
9561 => '??', // Aeromas — insufficient info
9589 => 'LV', // RAF-Avia — Latvia
9614 => 'GB', // Harrods Aviation — UK
9658 => 'EE', // SmartLynx Airlines Estonia — Estonia
9660 => '??', // Blocked
9664 => '??', // Mahfooz Aviation — insufficient info
9672 => 'SI', // North Adria Aviation — Slovenia
9685 => 'US', // NASA — USA
9704 => 'CA', // North Cariboo Air — Canada
9709 => 'NG', // Chanchangi Airlines — Nigeria
9724 => '??', // Blocked
9742 => 'NO', // Barents AirLink — Norway
9775 => 'US', // Angel Flight America — USA
9809 => '??', // Blocked
9823 => 'PT', // NetJets Europe — Portugal (EASA cert)
9862 => '??', // Blocked
9863 => '??', // Blocked
9864 => '??', // Blocked
9865 => '??', // Blocked
9866 => '??', // Blocked
9867 => '??', // Blocked
9868 => '??', // Blocked
9869 => '??', // Blocked
9870 => '??', // Blocked
9871 => '??', // Blocked
9872 => '??', // Blocked
9873 => '??', // Blocked
9874 => '??', // Blocked
9875 => '??', // Blocked
9876 => '??', // Blocked
9877 => '??', // Blocked
9878 => '??', // Blocked
9879 => '??', // Blocked
9880 => '??', // Blocked
9881 => '??', // Blocked
9882 => '??', // Blocked
9883 => '??', // Blocked
9884 => '??', // Blocked
9885 => '??', // Blocked
9886 => '??', // Blocked
9887 => '??', // Blocked
9916 => 'GB', // Atlantic Airlines — UK
9923 => 'NL', // North Sea Airways — Netherlands
9948 => 'CN', // Nanshan Jet — China
9961 => 'ES', // Canarias Airlines — Spain (Canary Islands)
9972 => 'JP', // Hokkaido Air System — Japan
10020 => 'NO', // AirWing — Norway
10022 => 'AU', // Network Aviation — Australia
10040 => 'MW', // Ulendo Airlink — Malawi
10041 => 'NZ', // Vincent Aviation Ltd. — New Zealand
10043 => '??', // Blocked
10045 => 'RU', // Alliance Avia — Russia
10087 => '??', // Blocked
10146 => 'PE', // CM Airlines — Peru
10149 => '??', // Blocked
10168 => 'US', // Flight Options — USA
10184 => 'CA', // Orca Airways — Canada
10239 => 'ES', // Aeronova — Spain
10259 => '??', // Blocked
10274 => 'CA', // Perimeter Aviation — Canada
10280 => 'BR', // MAP Linhas Aereas — Brazil
10282 => '??', // Blocked
10294 => 'US', // Presidential Airways — USA
10308 => 'WS', // Virgin Samoa — Samoa
10310 => 'NZ', // Virgin Australia (NZ) — New Zealand
10335 => 'US', // West Air (USA) — USA
10347 => '??', // Blocked
10352 => '??', // Blocked
10357 => 'FR', // Pan Europeenne Air Service — France
10372 => 'EG', // Petroleum Air Services — Egypt
10429 => 'AM', // Phoenix Avia — Armenia
10525 => '??', // Blocked
10589 => 'US', // PARS Systems — USA
10620 => '??', // S.A.P. — insufficient info
10622 => 'RU', // Pskovavia — Russia
10635 => 'DE', // PrivatAir Germany — Germany
10647 => 'JO', // Air Arabia Jordan — Jordan
10675 => 'US', // Privaira / Sky One Holdings — USA
10678 => '??', // Blocked
10680 => 'US', // Priester Aviation — USA
10703 => '??', // Blocked
10708 => '??', // Blocked
10709 => '??', // Blocked
10712 => 'QA', // Qatar Amiri Flight — Qatar
10724 => '??', // Blocked
10730 => 'UA', // Windrose Air — Ukraine
10739 => '??', // Blocked
10742 => 'NZ', // Jetconnect — New Zealand
10744 => '??', // Blocked
10746 => '??', // Blocked
10747 => '??', // Blocked
10752 => 'CA', // Gouvernement Du Quebec — Canada
10759 => '??', // Blocked
10765 => 'JP', // Ryukyu Air Commuter — Japan
10798 => 'US', // Rosenbalm Aviation — USA
10799 => '??', // Royal Air Charter — insufficient info
10862 => 'US', // Package Express, Inc. — USA
10863 => '??', // Blocked
10870 => 'RU', // Adygheya Avia — Russia
10882 => '??', // Blocked
10911 => '??', // Blocked
10949 => 'ES', // Cygnus Air — Spain
10968 => 'AR', // Ariella Airlines S.A. — Argentina
10972 => 'LV', // Riga Airlines — Latvia
10980 => 'BR', // Rio Linhas Aereas — Brazil
11009 => 'NZ', // Air Nelson — New Zealand
11017 => '??', // AirNow — insufficient info
11019 => '??', // S-Air — insufficient info
11056 => '??', // Blocked
11090 => 'US', // Republic Airlines — USA
11102 => '??', // Blocked
11107 => '??', // Blocked
11131 => 'ES', // Canarias Airlines — Spain
11136 => 'AE', // SNAS Aviation — UAE
11154 => '??', // Blocked
11155 => '??', // Blocked
11168 => '??', // Blocked
11175 => '??', // Blocked
11223 => 'AU', // Rex Regional Express — Australia
11227 => 'MA', // RAM Express — Morocco
11242 => 'ZW', // Royal Zimbabwe Airlines — Zimbabwe
11243 => '??', // Blocked
11250 => 'US', // Crossroads Aviation — USA
11316 => 'FI', // Snowbird Airlines Oy — Finland
11351 => '??', // Blocked
11463 => 'TR', // Saga Airlines — Turkey
11466 => 'GB', // Shell Aircraft — UK
11481 => 'GB', // British Airways Shuttle — UK
11491 => 'BR', // Sideral Linhas Aereas — Brazil
11509 => 'IT', // Sirio — Italy
11512 => 'RU', // Salair — Russia
11530 => 'US', // Sun Jet International Airlines — USA
11535 => 'CN', // Sino Jet — China
11557 => 'CA', // Skycharter — Canada
11563 => 'US', // LabCorp — USA
11580 => 'CZ', // Silver Air — Czech Republic
11590 => 'CA', // Skylink Aviation — Canada
11610 => 'BR', // SETE Linhas Aereas — Brazil
11648 => 'DE', // Senator Aviation Charter — Germany
11664 => 'IT', // Servizi Aerei — Italy
11666 => '??', // Blocked
11700 => 'SI', // Solinair — Slovenia
11701 => '??', // Blocked
11739 => 'GB', // Speedwings — UK
11748 => 'SG', // Singapore Airlines Cargo — Singapore
11778 => 'PL', // Sprint Air — Poland
11792 => '??', // Star Of Asia — insufficient info
11801 => 'SK', // Slovak Government Flying Service — Slovakia
11813 => 'AU', // Sunstate Airlines — Australia
11839 => '??', // Starwings International — insufficient info
11875 => 'PL', // Silesia Air — Poland
11877 => 'US', // Suburban Air Freight — USA
11909 => '??', // Blocked
11914 => 'SE', // Swedish Air Force — Sweden
11935 => 'LU', // Global Jet Luxembourg — Luxembourg
11958 => 'CH', // Swiss Global Air Lines — Switzerland
12010 => 'ZA', // South African Historic Flight — South Africa
12016 => '??', // Blocked
12032 => 'US', // TAG Aviation USA — USA
12034 => 'PF', // Air Moorea — French Polynesia
12054 => 'ES', // Air Iberia — Spain
12072 => 'IR', // ATA Airlines — Iran
12096 => '??', // Blocked
12100 => '??', // Tadair — insufficient info
12146 => 'KG', // Tez Jet — Kyrgyzstan
12150 => '??', // Blocked
12176 => 'CA', // Transport Canada — Canada
12198 => 'CA', // Thunder Airlines — Canada
12225 => 'AT', // Tyrolean Jet Service — Austria
12234 => 'RU', // Tretyakovo Air Transport — Russia
12259 => 'ES', // Top Fly — Spain
12302 => '??', // Blocked
12352 => 'MX', // TAPSA Aviacion — Mexico
12419 => 'RU', // Trast — Russia
12445 => 'BR', // Total Linhas Aereas — Brazil
12456 => '??', // Blocked
12463 => 'US', // Yute Air Alaska — USA
12476 => 'RU', // Tupolev-Aerotrans — Russia
12507 => 'FR', // Twinjet Aviation — France
12536 => 'US', // Texstar Air Freight — USA
12547 => 'AT', // Tyrol Air Ambulance — Austria
12550 => '??', // Blocked
12572 => 'UA', // Aviant — Ukraine
12578 => 'UA', // Antonov Airtrack — Ukraine
12601 => '??', // Blocked
12621 => 'RU', // Shar Ink — Russia
12637 => 'UA', // Ukraine Air Alliance — Ukraine
12673 => '??', // Blocked
12674 => '??', // United Nations — international body
12689 => 'UA', // Ukrainian Pilot School — Ukraine
12701 => 'AM', // Avia-Urartu — Armenia
12710 => 'US', // AirNet — USA
12740 => '??', // Blocked
12751 => 'CA', // Voyageur Airways — Canada
12755 => 'TH', // Phuket Air — Thailand
12792 => '??', // Blocked
12803 => 'VE', // Aeroejecutivos — Venezuela
12831 => 'GB', // Virgin Atlantic International — UK
12839 => 'RU', // Vologda Air Company — Russia
12848 => 'DE', // Vibro Air Flugservice — Germany
12911 => '??', // Blocked
12926 => 'UA', // Veteran Airlines — Ukraine
12929 => 'UA', // Veteran Air — Ukraine
12949 => '??', // Vertir Airlines — insufficient info
12970 => 'SI', // Aviostart — Slovenia
12979 => 'RU', // Vostok Airlines — Russia
12981 => 'MX', // Aeronaves TSM — Mexico
13020 => '??', // Blocked
13025 => 'GN', // Guinea Airlines — Guinea
13041 => 'US', // World Atlantic Airlines — USA
13069 => '??', // Blocked
13074 => 'DE', // WDL Aviation — Germany
13088 => '??', // Pronto Airways — insufficient info
13098 => 'US', // Vacation Express Public Charter — USA
13121 => 'US', // Wiggins Airways — USA
13122 => 'NZ', // Waikato Aero Club — New Zealand
744 => 'CA', // Hydro-Quebec — Canada
749 => 'GB', // British Airways Cargo — UK
750 => 'SG', // Sabre Asia Pacific Pte. Ltd. — Singapore
759 => 'GB', // Travelport International Operations — UK
760 => 'TW', // Eva Airways Cargo — Taiwan
761 => 'KR', // Asiana Airways Cargo — South Korea
762 => 'RU', // JSC Sirena-Travel — Russia
772 => 'HK', // Dragonair Cargo — Hong Kong
798 => '??', // GETS Marketing Company — insufficient info
806 => 'AL', // Albawings — Albania
808 => 'FR', // SNCF — France
816 => 'US', // Smokey Bay Air — USA (Alaska)
825 => 'BE', // Thalys International — Belgium
832 => '??', // Karlog Air — insufficient info
839 => '??', // Redemption Inc. — insufficient info
840 => '??', // Redemption Inc. — insufficient info
865 => 'US', // Amtrak — USA
878 => 'US', // Kenosha Aero dba Alliance Air — USA
879 => 'HK', // Chu Kong Passenger Transport — Hong Kong
893 => 'DE', // Dokasch GmbH — Germany
906 => 'MY', // Gading Sari Aviation Sdn Bhd — Malaysia
928 => 'DE', // Conatact Air — Germany
932 => 'MW', // Malawian Airlines — Malawi
934 => '??', // Premier Trans Aire — insufficient info
944 => 'US', // Aerodynamics, Inc. — USA
967 => 'GE', // Georgian International Airlines — Georgia
970 => '??', // Air Besit — insufficient info
975 => 'US', // Island Air — USA (Hawaii)
1005 => 'US', // Mercury Air Cargo, Inc. — USA
1006 => 'US', // Mercury World Cargo — USA
1025 => 'KE', // Five Fourty Aviation Limited — Kenya
1027 => 'ES', // Alsa Grupo SLU — Spain
1035 => '??', // ACM Air Charter — insufficient info
1049 => 'VE', // Rutas Aereas, C.A. — Venezuela
1066 => 'AT', // WESTbahn Management GmbH — Austria
1080 => 'ID', // PT. Pelita Air — Indonesia
1081 => 'SK', // Travel Service Slovensko s.r.o. — Slovakia
1103 => '??', // Zacarias Moreno — insufficient info
1111 => '??', // Gryphon Airlines — insufficient info
1120 => 'RU', // Alrosa Air — Russia
1122 => 'RU', // Open Joint Stock Company ALROSA — Russia
1130 => 'TC', // Turks Air — Turks and Caicos
1137 => 'ES', // Auto Res S.L.U. dba Avanza Group — Spain
1156 => '??', // MGC Aviation — insufficient info
1165 => 'US', // CSafe Global — USA
1175 => 'HU', // Travel Service Legiforgalmi — Hungary
1187 => 'EC', // Aero Express del Ecuador — Ecuador
1190 => 'US', // Alpha Air Transport — USA
1204 => 'US', // Ameristar Air Cargo, Inc. — USA
1205 => '??', // Skylanes — insufficient info
1208 => 'PA', // Panama Airways — Panama
1237 => '??', // Regional Air Services — insufficient info
1241 => 'CA', // West Coast Air — Canada (BC)
1250 => 'CA', // Air Tindi — Canada (NWT)
1254 => 'SR', // Fly All Ways — Suriname
1258 => 'SR', // Fly Always N.V. — Suriname
1269 => 'CA', // AccesRail and Partner Railways — Canada
1281 => 'GB', // Eurostar International Limited — UK
1284 => 'GB', // 9G Rail Limited — UK
1299 => '??', // West Link Airlines — insufficient info
1301 => '??', // West Link Airways — insufficient info
1310 => '??', // The Cargo Flights Co. — insufficient info
1323 => 'TR', // ACT Havayollari A.S. — Turkey
1338 => '??', // National Airways — insufficient info (multiple carriers)
1340 => 'AR', // Macair Jet S.A. — Argentina
];
public function up(): void
{
DB::table('countries')->insert([
'code' => '??',
'name' => '??',
'continent_id' => 1,
]);
DB::table('airlines')->where('country_code', 'AN')->update(['country_code' => 'CW']);
DB::table('airlines')->where('country_code', 'AX')->update(['country_code' => 'FI']);
DB::table('airlines')->where('country_code', 'CS')->update(['country_code' => 'RS']);
DB::table('airlines')->where('country_code', 'UK')->update(['country_code' => 'GB']);
DB::table('airlines')->where('country_code', 'YU')->update(['country_code' => 'RS']);
DB::table('airlines')->where('country_code', 'ZR')->update(['country_code' => 'CD']);
foreach ($this->map as $id => $code) {
DB::table('airlines')
->where('id', $id)
->whereNull('country_id')
->update(['country_code' => $code]);
}
DB::statement("
UPDATE airlines a
SET country_id = c.id
FROM countries c
WHERE c.code = a.country_code
AND a.country_id IS NULL
AND a.country_code != ''
");
Schema::table('airlines', function (Blueprint $table) {
$table->dropColumn(['country_code', 'country_name']);
$table->foreignId('country_id')->nullable(false)->change();
});
}
public function down(): void
{
$ids = array_keys(array_filter($this->map, fn($code) => $code !== '??'));
DB::table('airlines')
->whereIn('id', $ids)
->update(['country_code' => '']);
}
};
@@ -0,0 +1,55 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
DB::table('airlines')
->where('internal_name', 'gol-airlines')
->update([
'ICAO_code' => 'GLO',
'active' => true,
]);
DB::table('airlines')
->where('internal_name', 'jetgo')
->update([
'logo' => 'JG_1.png',
'active' => false,
]);
DB::table('airlines')
->where('internal_name', 'turpial')
->update([
'logo' => 'T9.png',
'IATA_code' => 'T9',
]);
}
public function down(): void
{
DB::table('airlines')
->where('internal_name', 'gol-airlines')
->update([
'ICAO_code' => '',
'active' => false,
]);
DB::table('airlines')
->where('internal_name', 'jetgo')
->update([
'logo' => 'JG.png',
'active' => true,
]);
DB::table('airlines')
->where('internal_name', 'turpial')
->update([
'logo' => '',
'IATA_code' => '',
]);
}
};
@@ -0,0 +1,51 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
private array $timezones = [
176 => 'Antarctica/Macquarie',
1012 => 'America/Iqaluit',
1129 => 'America/Iqaluit',
1153 => 'America/Iqaluit',
9241 => 'Asia/Anadyr',
9245 => 'Asia/Anadyr',
9364 => 'Europe/Moscow',
9365 => 'Asia/Krasnoyarsk',
11018 => 'Asia/Ulaanbaatar',
11019 => 'Asia/Ulaanbaatar',
];
public function up(): void
{
// 1. Populate timezones for the specific airports that were missing them
foreach ($this->timezones as $id => $timezone) {
DB::table('airports')
->where('id', $id)
->whereNull('timezone')
->update(['timezone' => $timezone]);
}
// 2. Make the timezone column non-nullable
Schema::table('airports', function (Blueprint $table) {
$table->string('timezone')->nullable(false)->change();
});
}
public function down(): void
{
// 1. Revert the column back to nullable first
Schema::table('airports', function (Blueprint $table) {
$table->string('timezone')->nullable()->change();
});
// 2. Null out only the rows we populated
DB::table('airports')
->whereIn('id', array_keys($this->timezones))
->update(['timezone' => null]);
}
};
@@ -0,0 +1,113 @@
<?php
use App\Models\Airline;
use App\Models\Airport;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Airport::where('iata_code', 'LZR')->update(['municipality' => 'Lizard Island']);
Airport::where('iata_code', 'SYD')->update(['municipality' => 'Sydney']);
Airport::where('iata_code', 'ISB')->update(['municipality' => 'Islamabad']);
Airport::where('iata_code', 'KUL')->update(['municipality' => 'Kuala Lumpur']);
Airport::where('iata_code', 'USM')->update(['municipality' => 'Ko Samui']);
Airport::where('iata_code', 'CDG')->update(['municipality' => 'Paris']);
Airport::where('iata_code', 'ORY')->update(['municipality' => 'Paris']);
Airport::where('iata_code', 'FRA')->update(['municipality' => 'Frankfurt']);
Airport::where('iata_code', 'EZE')->update(['municipality' => 'Buenos Aires']);
Airport::where('iata_code', 'PVG')->update(['municipality' => 'Shanghai']);
Airport::where('iata_code', 'MRU')->update(['municipality' => 'Mauritius']);
Airport::where('iata_code', 'HNL')->update(['municipality' => 'Honolulu']);
Airport::where('iata_code', 'NCL')->update(['municipality' => 'Newcastle upon Tyne']);
Airport::where('iata_code', 'KRK')->update(['municipality' => 'Krakow']);
Airport::where('iata_code', 'OTP')->update(['municipality' => 'Bucharest']);
Airport::where('iata_code', 'CAN')->update(['municipality' => 'Guangzhou']);
Airport::where('iata_code', 'XIY')->update(['municipality' => "Xi'an"]);
Airport::where('iata_code', 'ROR')->update(['municipality' => "Koror"]);
Airport::where('iata_code', 'WUH')->update(['municipality' => "Wuhan"]);
Airport::where('iata_code', 'CCS')->update(['municipality' => "Caracas"]);
Airport::where('iata_code', 'TFU')->update(['municipality' => "Chengdu"]);
Airport::where('iata_code', 'CTU')->update(['municipality' => "Chengdu"]);
Airport::where('iata_code', 'DMM')->update(['municipality' => "Dammam"]);
Airport::where('iata_code', 'VCE')->update(['municipality' => "Venice"]);
Airport::where('iata_code', 'MXP')->update(['municipality' => "Milan"]);
Airport::where('iata_code', 'DPS')->update(['municipality' => "Denpasar"]);
Airport::where('iata_code', 'CAY')->update(['municipality' => "Cayenne"]);
Airport::where('iata_code', 'LPA')->update(['municipality' => "Gran Canaria"]);
Airline::where('internal_name', 'thy-turkish-airlines')->update(['name' => 'Turkish Airlines']);
Airline::where('internal_name', 'air-china')->update(['name' => 'Air China']);
Airline::where('internal_name', 'jetstar-airways-pty')->update(['name' => 'Jetstar']);
Airline::where('internal_name', 'easyjet')->update(['name' => 'Easyjet']);
Airline::where('internal_name', 'china-west-air')->update(['name' => 'China West Air']);
Airline::where('internal_name', 'aeroenlaces-nacionales-s-a-de-c-v')->update(['name' => 'Viva']);
Airline::where('internal_name', 'aircompany-somon-air')->update(['name' => 'Somon Air']);
Airline::where('internal_name', 'hinterland-aviation-pty')->update(['name' => 'Hinterland Aviation']);
Airline::where('internal_name', 'mango-airlines-soc-trading-as-mango')->update(['name' => 'Mango']);
Airline::where('internal_name', 'air-manas-dba-air-manas-air')->update(['name' => 'Air Manas']);
Airline::where('internal_name', 'airasia-x-berhad-dba-airasia-x')->update(['name' => 'Air Asia X']);
Airline::where('internal_name', 'mesa-airlines')->update(['name' => 'Mesa Airlines']);
Airport::where('iata_code', 'MCT')->update(['municipality' => "Muscat"]);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Airport::where('iata_code', 'LZR')->update(['municipality' => '']);
Airport::where('iata_code', 'SYD')->update(['municipality' => 'Sydney (Mascot)']);
Airport::where('iata_code', 'ISB')->update(['municipality' => 'Attock']);
Airport::where('iata_code', 'KUL')->update(['municipality' => 'Sepang']);
Airport::where('iata_code', 'USM')->update(['municipality' => 'Na Thon (Ko Samui Island)']);
Airport::where('iata_code', 'CDG')->update(['municipality' => "Paris (Roissy-en-France, Val-d'Oise)"]);
Airport::where('iata_code', 'ORY')->update(['municipality' => "Paris (Orly, Val-de-Marne)"]);
Airport::where('iata_code', 'FRA')->update(['municipality' => 'Frankfurt am Main']);
Airport::where('iata_code', 'EZE')->update(['municipality' => 'Buenos Aires (Ezeiza)']);
Airport::where('iata_code', 'PVG')->update(['municipality' => 'Shanghai (Pudong)']);
Airport::where('iata_code', 'MRU')->update(['municipality' => 'Plaine Magnien']);
Airport::where('iata_code', 'HNL')->update(['municipality' => 'Honolulu, Oahu']);
Airport::where('iata_code', 'NCL')->update(['municipality' => 'Newcastle upon Tyne, Tyne and Wear']);
Airport::where('iata_code', 'KRK')->update(['municipality' => 'Balice']);
Airport::where('iata_code', 'OTP')->update(['municipality' => 'Otopeni']);
Airport::where('iata_code', 'CAN')->update(['municipality' => 'Guangzhou (Huadu)']);
Airport::where('iata_code', 'XIY')->update(['municipality' => "Xianyang (Weicheng)"]);
Airport::where('iata_code', 'ROR')->update(['municipality' => "Babelthuap Island"]);
Airport::where('iata_code', 'WUH')->update(['municipality' => "Wuhan (Huangpi)"]);
Airport::where('iata_code', 'CCS')->update(['municipality' => "Maiquetía"]);
Airport::where('iata_code', 'TFU')->update(['municipality' => "Chengdu (Jianyang)"]);
Airport::where('iata_code', 'CTU')->update(['municipality' => "Chengdu (Shuangliu)"]);
Airport::where('iata_code', 'DMM')->update(['municipality' => "Ad Dammam"]);
Airport::where('iata_code', 'VCE')->update(['municipality' => "Venezia (VE)"]);
Airport::where('iata_code', 'MXP')->update(['municipality' => "Ferno (VA)"]);
Airport::where('iata_code', 'DPS')->update(['municipality' => "Kuta, Badung"]);
Airport::where('iata_code', 'CAY')->update(['municipality' => "Matoury"]);
Airport::where('iata_code', 'LPA')->update(['municipality' => "Gran Canaria Island"]);
Airport::where('iata_code', 'MCT')->update(['municipality' => "Muscat/Seeb"]);
Airline::where('internal_name', 'thy-turkish-airlines')->update(['name' => ' THY - Turkish Airlines']);
Airline::where('internal_name', 'air-china')->update(['name' => 'Air China Limited']);
Airline::where('internal_name', 'jetstar-airways-pty')->update(['name' => 'Jetstar Airways Pty Limited']);
Airline::where('internal_name', 'easyjet')->update(['name' => 'Easyjet Airline Company Limited']);
Airline::where('internal_name', 'china-west-air')->update(['name' => 'China West Air Co. Ltd.']);
Airline::where('internal_name', 'aeroenlaces-nacionales-s-a-de-c-v')->update(['name' => 'Aeroenlaces Nacionales S.A. De C.V.']);
Airline::where('internal_name', 'aircompany-somon-air')->update(['name' => 'Aircompany Somon Air LLC']);
Airline::where('internal_name', 'hinterland-aviation-pty')->update(['name' => 'Hinterland Aviation Pty Ltd']);
Airline::where('internal_name', 'mango-airlines-soc-trading-as-mango')->update(['name' => 'Mango Airlines (SOC) Ltd trading as MANGO']);
Airline::where('internal_name', 'air-manas-dba-air-manas-air')->update(['name' => 'Air Manas dba Air Manas ltd. Air Company']);
Airline::where('internal_name', 'airasia-x-berhad-dba-airasia-x')->update(['name' => 'Airasia X Berhad dba Airasia X']);
Airline::where('internal_name', 'mesa-airlines')->update(['name' => 'Mesa Airlines, Inc']);
}
};
@@ -0,0 +1,30 @@
<?php
use App\Models\Airline;
use App\Models\Country;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$northKorea = Country::where('code', 'KP')->first();
Airline::where('internal_name', 'air-koryo')->update(['country_id' => $northKorea->id]);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$southKorea = Country::where('code', 'KR')->first();
Airline::where('internal_name', 'air-koryo')->update(['country_id' => $southKorea->id]);
}
};
@@ -0,0 +1,22 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('user_flights', function (Blueprint $table) {
$table->boolean('auto_update')->default(false)->after('note');
});
}
public function down(): void
{
Schema::table('user_flights', function (Blueprint $table) {
$table->dropColumn('auto_update');
});
}
};
@@ -0,0 +1,972 @@
<?php
use App\Http\Controllers\LogoController;
use App\Models\Airline;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('airlines', function (Blueprint $table) {
$table->string('logo', 255)->nullable()->change();
});
LogoController::nullMissingLogoFiles();
$this->deDuplicateLogos();
$this->checkNonDuplicateLogos();
Airline::whereNull('logo')->delete();
}
private function checkNonDuplicateLogos(){
LogoController::deduplicateLogo('0V.png', ['vasco']);
LogoController::deduplicateLogo('2I.png', ['star-up']);
LogoController::deduplicateLogo('2H.png', []);
LogoController::deduplicateLogo('2J.png', ['air-burkina']);
LogoController::deduplicateLogo('2M.png', []);
LogoController::deduplicateLogo('2P.png', ['air-philippines-corporation-dba-pal-express-and-airphil-express']);
LogoController::deduplicateLogo('2R.png', []);
LogoController::deduplicateLogo('3F.png', []);
LogoController::deduplicateLogo('3H.png', ['air-inuit-ltd-ltee']);
LogoController::deduplicateLogo('3R.png', []);
LogoController::deduplicateLogo('3S.png', []);
LogoController::deduplicateLogo('3U.png', ['sichuan-airlines']);
LogoController::deduplicateLogo('4C.png', ['lan-colombia-airlines']);
LogoController::deduplicateLogo('4D.png', []);
LogoController::deduplicateLogo('4G.png', ['gazpromavia-aviation-ltd']);
LogoController::deduplicateLogo('4I.png', []);
LogoController::deduplicateLogo('4K.png', []);
LogoController::deduplicateLogo('4N.png', ['air-north-charter-and-training']);
LogoController::deduplicateLogo('4W.png', []);
LogoController::deduplicateLogo('4Z.png', ['airlink']);
LogoController::deduplicateLogo('5A.png', []);
LogoController::deduplicateLogo('5C.png', []);
LogoController::deduplicateLogo('5G.png', []);
LogoController::deduplicateLogo('5J.png', ['cebu-pacific-air']);
LogoController::deduplicateLogo('5K.png', []);
LogoController::deduplicateLogo('5M.png', []);
LogoController::deduplicateLogo('5N.png', []);
LogoController::deduplicateLogo('5U.png', ['transportes-aereos-guatemaltecos-s']);
LogoController::deduplicateLogo('5X.png', ['ups-airlines']);
LogoController::deduplicateLogo('6H.png', ['israir']);
LogoController::deduplicateLogo('6L.png', ['aklak']);
LogoController::deduplicateLogo('6O.png', []);
LogoController::deduplicateLogo('6W.png', []);
LogoController::deduplicateLogo('7J.png', ['ojsc-tajik-air']);
LogoController::deduplicateLogo('7R.png', ['joint-stock-aviation-rusline']);
LogoController::deduplicateLogo('8D.png', ['fitsair']);
LogoController::deduplicateLogo('8E.png', ['bering-air']);
LogoController::deduplicateLogo('8N.png', ['regional-air']);
LogoController::deduplicateLogo('8T.png', ['air-tindi-8t']);
LogoController::deduplicateLogo('8V.png', []);
LogoController::deduplicateLogo('8Z.png', []);
LogoController::deduplicateLogo('9C.png', []);
LogoController::deduplicateLogo('9M.png', []);
LogoController::deduplicateLogo('9Q.png', ['caicos-express-airways']);
LogoController::deduplicateLogo('A0.png', []);
LogoController::deduplicateLogo('A3.png', ['aegean-airlines']);
LogoController::deduplicateLogo('A4.png', []);
LogoController::deduplicateLogo('A5.png', ['hop']);
LogoController::deduplicateLogo('A6.png', []);
LogoController::deduplicateLogo('A8.png', []);
LogoController::deduplicateLogo('A9.png', ['georgian-airways']);
LogoController::deduplicateLogo('AA.png', ['american-airlines']);
LogoController::deduplicateLogo('AB.png', ['bonza']);
LogoController::deduplicateLogo('AC.png', ['air-canada']);
LogoController::deduplicateLogo('AF.png', ['air-france']);
LogoController::deduplicateLogo('AH.png', ['air-algerie']);
LogoController::deduplicateLogo('AI.png', ['air-india']);
LogoController::deduplicateLogo('AR.png', ['aerolineas-argentinas']);
LogoController::deduplicateLogo('AS.png', ['alaska-airlines']);
LogoController::deduplicateLogo('AT.png', ['royal-air-maroc']);
LogoController::deduplicateLogo('AV.png', ['avianca']);
LogoController::deduplicateLogo('AY.png', ['finnair']);
LogoController::deduplicateLogo('AZ.png', ['alitalia']);
LogoController::deduplicateLogo('B0.png', ['dreamjet-sas-t-a-la-compagnie']);
LogoController::deduplicateLogo('B2.png', ['belavia-belarusian-airlines']);
LogoController::deduplicateLogo('B4.png', []);
LogoController::deduplicateLogo('B9.png', ['iran-air-tours']);
LogoController::deduplicateLogo('BP.png', ['air-botswana']);
LogoController::deduplicateLogo('BW.png', ['caribbean-airlines']);
LogoController::deduplicateLogo('BY.png', []);
LogoController::deduplicateLogo('CI.png', ['china-airlines']);
LogoController::deduplicateLogo('CM_1.png', ['copa-airlines']);
LogoController::deduplicateLogo('CO_1.png', ['continental-airlines']);
LogoController::deduplicateLogo('CU.png', ['cubana']);
LogoController::deduplicateLogo('CX.png', ['cathay-pacific']);
LogoController::deduplicateLogo('CY.png', ['cyprus-airways']);
LogoController::deduplicateLogo('D0.png', ['dhl-air']);
LogoController::deduplicateLogo('D3.png', ['daallo-airlines']);
LogoController::deduplicateLogo('D4.png', []);
LogoController::deduplicateLogo('D6.png', []);
LogoController::deduplicateLogo('D8.png', ['norwegian-air-international']);
LogoController::deduplicateLogo('D9.png', []);
LogoController::deduplicateLogo('DE.png', ['condor']);
LogoController::deduplicateLogo('DJ_1.png', ['virgin-blue-airlines']);
LogoController::deduplicateLogo('DL.png', ['delta-air-lines']);
LogoController::deduplicateLogo('DT.png', ['taag-angola-airlines']);
LogoController::deduplicateLogo('EI.png', ['aer-lingus']);
LogoController::deduplicateLogo('ET.png', ['ethiopian-airlines']);
LogoController::deduplicateLogo('FG.png', ['ariana-afghan-airlines']);
LogoController::deduplicateLogo('FI.png', ['icelandair']);
LogoController::deduplicateLogo('FJ.png', ['air-pacific']);
LogoController::deduplicateLogo('G4.png', ['allegiant-air']);
LogoController::deduplicateLogo('G5.png', ['china-express-airlines']);
LogoController::deduplicateLogo('G9.png', ['air-arabia']);
LogoController::deduplicateLogo('GA.png', ['garuda']);
LogoController::deduplicateLogo('GL.png', ['air-greenland-a-s']);
LogoController::deduplicateLogo('GU.png', []);
LogoController::deduplicateLogo('H2.png', []);
LogoController::deduplicateLogo('HA.png', ['hawaiian-airlines']);
LogoController::deduplicateLogo('HF.png', ['air-cote-d-ivoire']);
LogoController::deduplicateLogo('I4.png', ['scott-air']);
LogoController::deduplicateLogo('I7.png', []);
LogoController::deduplicateLogo('I9.png', []);
LogoController::deduplicateLogo('IA.png', ['iraqi-airways']);
LogoController::deduplicateLogo('IB.png', ['iberia']);
LogoController::deduplicateLogo('IC.png', []);
LogoController::deduplicateLogo('IE.png', ['solomon-airlines']);
LogoController::deduplicateLogo('IG.png', []);
LogoController::deduplicateLogo('IR.png', ['iran-air']);
LogoController::deduplicateLogo('IY.png', ['yemenia']);
LogoController::deduplicateLogo('IZ.png', ['arkia-israeli-airlines']);
LogoController::deduplicateLogo('J0.png', []);
LogoController::deduplicateLogo('J2.png', ['azerbaijan-airlines']);
LogoController::deduplicateLogo('J3.png', ['northwestern-air-lease']);
LogoController::deduplicateLogo('J8.png', ['berjaya-air-sdn-bhd']);
LogoController::deduplicateLogo('JG_1.png', ['jetgo']);
LogoController::deduplicateLogo('JJ.png', ['tam-linhas-aereas']);
LogoController::deduplicateLogo('JL.png', ['japan-airlines']);
LogoController::deduplicateLogo('JV.png', ['bearskin-lake-air-lp']);
LogoController::deduplicateLogo('K2.png', []);
LogoController::deduplicateLogo('K3.png', []);
LogoController::deduplicateLogo('KE.png', ['korean-air']);
LogoController::deduplicateLogo('KL.png', ['klm']);
LogoController::deduplicateLogo('KM.png', ['air-malta']);
LogoController::deduplicateLogo('KU.png', ['kuwait-airways']);
LogoController::deduplicateLogo('KX.png', ['cayman-airways']);
LogoController::deduplicateLogo('L5.png', []);
LogoController::deduplicateLogo('LA.png', ['lan-airlines']);
LogoController::deduplicateLogo('LG.png', ['luxair']);
LogoController::deduplicateLogo('LO.png', ['lot-polish-airlines']);
LogoController::deduplicateLogo('LR.png', []);
LogoController::deduplicateLogo('LT.png', []);
LogoController::deduplicateLogo('LY.png', ['el-al-israel-airlines']);
LogoController::deduplicateLogo('M0.png', ['aero-mongolia']);
LogoController::deduplicateLogo('M3.png', []);
LogoController::deduplicateLogo('M5.png', ['kenmore-air']);
LogoController::deduplicateLogo('M9.png', ['motor-sich-jsc']);
LogoController::deduplicateLogo('ME.png', ['mea']);
LogoController::deduplicateLogo('MH.png', ['malaysia-airlines']);
LogoController::deduplicateLogo('MK.png', ['air-mauritius']);
LogoController::deduplicateLogo('MM.png', ['peach-aviation']);
LogoController::deduplicateLogo('MN.png', []);
LogoController::deduplicateLogo('MX.png', []);
LogoController::deduplicateLogo('NH.png', ['all-nippon-airways']);
LogoController::deduplicateLogo('O3.png', ['sf-airlines-limited']);
LogoController::deduplicateLogo('O4.png', []);
LogoController::deduplicateLogo('OA.png', ['olympic-air']);
LogoController::deduplicateLogo('OM.png', ['miat-mongolian-airlines']);
LogoController::deduplicateLogo('ON.png', ['nauru-air-corporation-t-a-our-airline']);
LogoController::deduplicateLogo('OO.png', ['skywest-airlines']);
LogoController::deduplicateLogo('OS.png', ['austrian']);
LogoController::deduplicateLogo('P0.png', ['proflight-zambia']);
LogoController::deduplicateLogo('P2.png', ['airkenya-express']);
LogoController::deduplicateLogo('P5.png', []);
LogoController::deduplicateLogo('P6.png', ['privilege-style-s-a']);
LogoController::deduplicateLogo('PH.png', []);
LogoController::deduplicateLogo('PK.png', ['pia']);
LogoController::deduplicateLogo('PR.png', ['philippine-airlines']);
LogoController::deduplicateLogo('PY.png', ['surinam-airways']);
LogoController::deduplicateLogo('PZ.png', []);
LogoController::deduplicateLogo('Q2.png', []);
LogoController::deduplicateLogo('QF.png', ['qantas']);
LogoController::deduplicateLogo('QI.png', []);
LogoController::deduplicateLogo('QM.png', ['monacair']);
LogoController::deduplicateLogo('R2.png', []);
LogoController::deduplicateLogo('R7.png', []);
LogoController::deduplicateLogo('RA.png', ['nepal-airlines-corporation']);
LogoController::deduplicateLogo('RB.png', ['syrianair']);
LogoController::deduplicateLogo('RJ.png', ['royal-jordanian']);
LogoController::deduplicateLogo('RO.png', ['tarom']);
LogoController::deduplicateLogo('RR.png', []);
LogoController::deduplicateLogo('S2.png', []);
LogoController::deduplicateLogo('S4.png', ['sata-internacional']);
LogoController::deduplicateLogo('S7.png', ['s7-airlines']);
LogoController::deduplicateLogo('SA.png', ['saa']);
LogoController::deduplicateLogo('SD.png', ['sudan-airways']);
LogoController::deduplicateLogo('SK.png', ['sas']);
LogoController::deduplicateLogo('SN.png', ['brussels-airlines']);
LogoController::deduplicateLogo('SU.png', ['aeroflot']);
LogoController::deduplicateLogo('SV.png', ['saudi-arabian-airlines']);
LogoController::deduplicateLogo('TG.png', ['thai-airways-international']);
LogoController::deduplicateLogo('TK.png', ['thy-turkish-airlines']);
LogoController::deduplicateLogo('TP.png', ['tap-portugal']);
LogoController::deduplicateLogo('TU.png', ['tunisair']);
LogoController::deduplicateLogo('TY.png', ['air-caledonie']);
LogoController::deduplicateLogo('U2.png', ['easyjet']);
LogoController::deduplicateLogo('U5.png', []);
LogoController::deduplicateLogo('U6.png', ['ural-airlines']);
LogoController::deduplicateLogo('UT.png', ['utair']);
LogoController::deduplicateLogo('UU.png', ['air-austral']);
LogoController::deduplicateLogo('V0.png', ['conviasa']);
LogoController::deduplicateLogo('V7.png', ['volotea']);
LogoController::deduplicateLogo('VA_2.png', ['v-australia']);
LogoController::deduplicateLogo('VO.png', []);
LogoController::deduplicateLogo('VR.png', ['tacv-cabo-verde-airlines']);
LogoController::deduplicateLogo('VT.png', ['air-tahiti']);
LogoController::deduplicateLogo('W5.png', ['mahan-air']);
LogoController::deduplicateLogo('WF.png', ['wideroe']);
LogoController::deduplicateLogo('WM.png', []);
LogoController::deduplicateLogo('WY.png', ['oman-air']);
LogoController::deduplicateLogo('X1.png', []);
LogoController::deduplicateLogo('X7.png', []);
LogoController::deduplicateLogo('XQ.png', ['sunexpress']);
LogoController::deduplicateLogo('XR_1.png', ['skywest']);
LogoController::deduplicateLogo('XZ.png', []);
LogoController::deduplicateLogo('Y3.png', []);
LogoController::deduplicateLogo('Y8.png', []);
LogoController::deduplicateLogo('Y9.png', []);
LogoController::deduplicateLogo('YB.png', []);
LogoController::deduplicateLogo('YG.png', ['yto-cargo-airlines']);
LogoController::deduplicateLogo('YL.png', ['libyan-wings']);
LogoController::deduplicateLogo('YN.png', ['air-creebec-1994']);
LogoController::deduplicateLogo('YR.png', ['grand-canyon-airlines']);
LogoController::deduplicateLogo('YS.png', []);
LogoController::deduplicateLogo('YV.png', ['mesa-airlines']);
LogoController::deduplicateLogo('YX.png', ['republic-airline']);
LogoController::deduplicateLogo('Z3.png', []);
LogoController::deduplicateLogo('Z6.png', []);
LogoController::deduplicateLogo('ZD.png', ['ewa-air']);
LogoController::deduplicateLogo('ZK.png', []);
LogoController::deduplicateLogo('ZW.png', ['air-wisconsin-airlines-corporation-awac']);
}
private function deDuplicateLogos(){
LogoController::deduplicateLogo('VA.png', ['virgin-australia', 'virgin-australia-regional']);
LogoController::deduplicateLogo('2A.png', []);
LogoController::deduplicateLogo('2C.png', []);
LogoController::deduplicateLogo('2D.png', []);
LogoController::deduplicateLogo('2F.png', []);
LogoController::deduplicateLogo('2G.png', []);
LogoController::deduplicateLogo('2K.png', ['aerogal']);
LogoController::deduplicateLogo('2L.png', ['helvetic-airways-ag']);
LogoController::deduplicateLogo('2N.png', []);
LogoController::deduplicateLogo('2S.png', []);
LogoController::deduplicateLogo('2T.png', []);
LogoController::deduplicateLogo('2U.png', []);
LogoController::deduplicateLogo('2W.png', []);
LogoController::deduplicateLogo('2Y.png', []);
LogoController::deduplicateLogo('3A.png', []);
LogoController::deduplicateLogo('3B.png', []);
LogoController::deduplicateLogo('3C.png', []);
LogoController::deduplicateLogo('3E.png', []);
LogoController::deduplicateLogo('3G.png', []);
LogoController::deduplicateLogo('3L.png', []);
LogoController::deduplicateLogo('3N.png', ['air-urga']);
LogoController::deduplicateLogo('3O.png', ['air-arabia-maroc']);
LogoController::deduplicateLogo('3P.png', []);
LogoController::deduplicateLogo('3T.png', ['tarco-air']);
LogoController::deduplicateLogo('3V.png', ['tnt-airways-s-a']);
LogoController::deduplicateLogo('3W.png', ['malawian-airlines-3w']);
LogoController::deduplicateLogo('3Z.png', []);
LogoController::deduplicateLogo('4A.png', []);
LogoController::deduplicateLogo('4B.png', ['boutique-air']);
LogoController::deduplicateLogo('4F.png', []);
LogoController::deduplicateLogo('4H.png', []);
LogoController::deduplicateLogo('4K.png', []);
LogoController::deduplicateLogo('4L.png', []);
LogoController::deduplicateLogo('4M.png', []);
LogoController::deduplicateLogo('4O.png', []);
LogoController::deduplicateLogo('4R.png', []);
LogoController::deduplicateLogo('4S.png', []);
LogoController::deduplicateLogo('4T.png', []);
LogoController::deduplicateLogo('4U.png', []);
LogoController::deduplicateLogo('4X.png', []);
LogoController::deduplicateLogo('4Y.png', []);
LogoController::deduplicateLogo('5B.png', []);
LogoController::deduplicateLogo('5D.png', []);
LogoController::deduplicateLogo('5F.png', ['fly-one-s-r-l']);
LogoController::deduplicateLogo('5H.png', []);
LogoController::deduplicateLogo('5H.png', []);
LogoController::deduplicateLogo('5I.png', ['alsa-grupo-slu']);
LogoController::deduplicateLogo('5L.png', ['asl-airlines-france']);
LogoController::deduplicateLogo('5O.png', []);
LogoController::deduplicateLogo('5R.png', ['rutaca-airlines']);
LogoController::deduplicateLogo('5T.png', ['canadian-north']);
LogoController::deduplicateLogo('5Y.png', ['atlas-air']);
LogoController::deduplicateLogo('5Z.png', ['cemair']);
LogoController::deduplicateLogo('6A.png', ['armenia-airways-aircompany-cjsc']);
LogoController::deduplicateLogo('6B.png', ['tuifly-nordic-ab']);
LogoController::deduplicateLogo('6D.png', []);
LogoController::deduplicateLogo('6E.png', ['interglobe-aviation-dba-indigo']);
LogoController::deduplicateLogo('6F.png', []);
LogoController::deduplicateLogo('6G.png', []);
LogoController::deduplicateLogo('6J.png', ['solaseed-air']);
LogoController::deduplicateLogo('6K.png', []);
LogoController::deduplicateLogo('6N.png', ['niger-airlines-s-a']);
LogoController::deduplicateLogo('6P.png', []);
LogoController::deduplicateLogo('6R.png', ['alrosa-air', 'alrosa-mirny-air-enterprise', 'open-joint-stock-alrosa-mirny-air-enterprise']);
LogoController::deduplicateLogo('6V.png', []);
LogoController::deduplicateLogo('7B.png', []);
LogoController::deduplicateLogo('7C.png', ['jeju-air']);
LogoController::deduplicateLogo('7E.png', ['sylt-air-gmbh']);
LogoController::deduplicateLogo('7G.png', ['star-flyer']);
LogoController::deduplicateLogo('7I.png', ['inselair']);
LogoController::deduplicateLogo('7K.png', []);
LogoController::deduplicateLogo('7L.png', ['silk-way-west-airlines']);
LogoController::deduplicateLogo('7O.png', []);
LogoController::deduplicateLogo('7P.png', ['air-panama-dba-parsa']);
LogoController::deduplicateLogo('7Q.png', []);
LogoController::deduplicateLogo('7T.png', []);
LogoController::deduplicateLogo('7V.png', ['federal-air']);
LogoController::deduplicateLogo('7W.png', ['wind-rose-aviation']);
LogoController::deduplicateLogo('7Y.png', ['mann-yadanarpon-airlines']);
LogoController::deduplicateLogo('7Z.png', ['']);
LogoController::deduplicateLogo('8B.png', ['pt-transnusa-aviation-mandiri']);
LogoController::deduplicateLogo('8C.png', ['']);
LogoController::deduplicateLogo('8F.png', ['stp-airways']);
LogoController::deduplicateLogo('8G.png', []);
LogoController::deduplicateLogo('8H.png', ['bh-air']);
LogoController::deduplicateLogo('8J.png', ['linea-aerea-eco-jet-s-a']);
LogoController::deduplicateLogo('8K.png', ['k-mile-air']);
LogoController::deduplicateLogo('8L.png', ['lucky-air']);
LogoController::deduplicateLogo('8M.png', ['myanmar-airways-international']);
LogoController::deduplicateLogo('8R.png', []);
LogoController::deduplicateLogo('8S.png', []);
LogoController::deduplicateLogo('8U.png', ['afriqiyah-airways']);
LogoController::deduplicateLogo('8W.png', ['fly-all-ways', 'fly-always-n-v']);
LogoController::deduplicateLogo('8Y.png', []);
LogoController::deduplicateLogo('9D.png', []);
LogoController::deduplicateLogo('9E.png', ['endeavor-air']);
LogoController::deduplicateLogo('9F.png', []);
LogoController::deduplicateLogo('9G.png', []);
LogoController::deduplicateLogo('9H.png', ['chang-an-airlines']);
LogoController::deduplicateLogo('9I.png', ['airline-allied-limited-dba-alliance-air']);
LogoController::deduplicateLogo('9K.png', ['cape-air']);
LogoController::deduplicateLogo('9N.png', ['tropic-air']);
LogoController::deduplicateLogo('9P.png', []);
LogoController::deduplicateLogo('9R.png', []);
LogoController::deduplicateLogo('9S.png', []);
LogoController::deduplicateLogo('9T.png', []);
LogoController::deduplicateLogo('9V.png', ['c-a']);
LogoController::deduplicateLogo('9X.png', ['southern-airways-express']);
LogoController::deduplicateLogo('9Y.png', []);
LogoController::deduplicateLogo('A2.png', []);
LogoController::deduplicateLogo('A7.png', []);
LogoController::deduplicateLogo('AD.png', ['azul-brazilian-airlines']);
LogoController::deduplicateLogo('AE.png', ['mandarin-airlines']);
LogoController::deduplicateLogo('AG.png', []);
LogoController::deduplicateLogo('AJ.png', ['aztec-worldwide-airlines']);
LogoController::deduplicateLogo('AK.png', ['airasia-berhad-dba-airasia']);
LogoController::deduplicateLogo('AM.png', ['aeromexico']);
LogoController::deduplicateLogo('AN.png', []);
LogoController::deduplicateLogo('AO.png', []);
LogoController::deduplicateLogo('AP.png', []);
LogoController::deduplicateLogo('AQ.png', ['nine-air']);
LogoController::deduplicateLogo('AW.png', ['africa-world-airlines']);
LogoController::deduplicateLogo('AX.png', []);
LogoController::deduplicateLogo('B3.png', ['bhutan-airlines']);
LogoController::deduplicateLogo('B6.png', ['jetblue']);
LogoController::deduplicateLogo('B7.png', []);
LogoController::deduplicateLogo('BA.png', ['british-airways']);
LogoController::deduplicateLogo('BB.png', ['seaborne-airlines']);
LogoController::deduplicateLogo('BC.png', ['skymark-airlines']);
LogoController::deduplicateLogo('BE.png', []);
LogoController::deduplicateLogo('BF.png', []);
LogoController::deduplicateLogo('BG.png', ['biman']);
LogoController::deduplicateLogo('BH.png', []);
LogoController::deduplicateLogo('BI.png', ['royal-brunei']);
LogoController::deduplicateLogo('BJ.png', ['nouvelair']);
LogoController::deduplicateLogo('BK.png', ['okay-airways']);
LogoController::deduplicateLogo('BL.png', []);
LogoController::deduplicateLogo('BM.png', []);
LogoController::deduplicateLogo('BQ.png', []);
LogoController::deduplicateLogo('BR.png', ['eva-air']);
LogoController::deduplicateLogo('BS.png', ['us-bangla-airlines']);
LogoController::deduplicateLogo('BT.png', ['air-baltic']);
LogoController::deduplicateLogo('BU.png', ['compagnie-africaine-d-aviation-caa']);
LogoController::deduplicateLogo('BV.png', []);
LogoController::deduplicateLogo('BX.png', ['air-busan']);
LogoController::deduplicateLogo('BZ.png', ['']);
LogoController::deduplicateLogo('C3.png', ['trade-air']);
LogoController::deduplicateLogo('C5.png', ['commutair']);
LogoController::deduplicateLogo('C6.png', []);
LogoController::deduplicateLogo('C7.png', ['cinnamon-air']);
LogoController::deduplicateLogo('C8.png', ['cargolux-italia-s-p-a']);
LogoController::deduplicateLogo('C9.png', []);
LogoController::deduplicateLogo('CA.png', ['air-china']);
LogoController::deduplicateLogo('CB.png', []);
LogoController::deduplicateLogo('CD.png', ['corendon-dutch-airlines-b-v']);
LogoController::deduplicateLogo('CE.png', ['chalair-aviation']);
LogoController::deduplicateLogo('CF.png', ['china-postal-airlines']);
LogoController::deduplicateLogo('CG.png', ['airlines-of-papua-new-guinea']);
LogoController::deduplicateLogo('CH.png', []);
LogoController::deduplicateLogo('CJ.png', ['ba-cityflyer']);
LogoController::deduplicateLogo('CL.png', ['lufthansa-cityline']);
LogoController::deduplicateLogo('CN.png', ['grand-china-air']);
LogoController::deduplicateLogo('CO.png', []);
LogoController::deduplicateLogo('CP.png', []);
LogoController::deduplicateLogo('CQ.png', ['coastal-aviation', 'coastal-travels-cq']);
LogoController::deduplicateLogo('CS.png', []);
LogoController::deduplicateLogo('CV.png', ['cargolux-s-a']);
LogoController::deduplicateLogo('CW.png', []);
LogoController::deduplicateLogo('CZ.png', ['china-southern-airlines']);
LogoController::deduplicateLogo('D2.png', ['severstal-aircompany']);
LogoController::deduplicateLogo('D5.png', ['dhl-aero-expreso-s-a']);
LogoController::deduplicateLogo('D7.png', ['airasia-x-berhad-dba-airasia-x', 'airasia-x-malaysia']);
LogoController::deduplicateLogo('DD.png', ['nok-airlines-public-limited-dba-nok-air']);
LogoController::deduplicateLogo('DG.png', []);
LogoController::deduplicateLogo('DH.png', []);
LogoController::deduplicateLogo('DI.png', []);
LogoController::deduplicateLogo('DJ.png', []);
LogoController::deduplicateLogo('DK.png', []);
LogoController::deduplicateLogo('DM.png', []);
LogoController::deduplicateLogo('DN.png', []);
LogoController::deduplicateLogo('DO.png', []);
LogoController::deduplicateLogo('DP.png', ['pobeda']);
LogoController::deduplicateLogo('DQ.png', []);
LogoController::deduplicateLogo('DR.png', ['ruili-airlines']);
LogoController::deduplicateLogo('DS.png', ['easyjet-switzerland-s-a']);
LogoController::deduplicateLogo('DU.png', []);
LogoController::deduplicateLogo('DV.png', ['jsc-aircompany-scat']);
LogoController::deduplicateLogo('DX.png', ['danish-air-transport']);
LogoController::deduplicateLogo('DY.png', ['norwegian-air-shuttle-a-s']);
LogoController::deduplicateLogo('DZ.png', ['donghai-airlines']);
LogoController::deduplicateLogo('E2.png', ['eurowings-europe-gmbh']);
LogoController::deduplicateLogo('E4.png', []);
LogoController::deduplicateLogo('E5.png', ['air-arabia-egypt']);
LogoController::deduplicateLogo('E6.png', []);
LogoController::deduplicateLogo('E9.png', []);
LogoController::deduplicateLogo('EA.png', []);
LogoController::deduplicateLogo('EB.png', ['wamos-air']);
LogoController::deduplicateLogo('EC.png', []);
LogoController::deduplicateLogo('ED.png', ['airexplore']);
LogoController::deduplicateLogo('EG.png', []);
LogoController::deduplicateLogo('EH.png', ['ana-wings']);
LogoController::deduplicateLogo('EJ.png', []);
LogoController::deduplicateLogo('EK.png', ['emirates']);
LogoController::deduplicateLogo('EN.png', []);
LogoController::deduplicateLogo('EO.png', []);
LogoController::deduplicateLogo('EP.png', ['iran-aseman-airlines']);
LogoController::deduplicateLogo('EQ.png', []);
LogoController::deduplicateLogo('ER.png', []);
LogoController::deduplicateLogo('ES.png', []);
LogoController::deduplicateLogo('EU.png', ['chengdu-airlines']);
LogoController::deduplicateLogo('EW.png', ['eurowings']);
LogoController::deduplicateLogo('EX.png', []);
LogoController::deduplicateLogo('EY.png', ['etihad-airways']);
LogoController::deduplicateLogo('EZ.png', ['sun-air-of-scandinavia-a-s']);
LogoController::deduplicateLogo('F2.png', []);
LogoController::deduplicateLogo('F4.png', []);
LogoController::deduplicateLogo('F5.png', ['aerotranscargo']);
LogoController::deduplicateLogo('F6.png', []);
LogoController::deduplicateLogo('F7.png', []);
LogoController::deduplicateLogo('F8.png', ['flair-airlines']);
LogoController::deduplicateLogo('F9.png', ['frontier', 'frontier-airlines']);
LogoController::deduplicateLogo('FA.png', ['safair']);
LogoController::deduplicateLogo('FB.png', ['bulgaria-air']);
LogoController::deduplicateLogo('FC.png', []);
LogoController::deduplicateLogo('FD.png', ['thai-airasia']);
LogoController::deduplicateLogo('FE.png', []);
LogoController::deduplicateLogo('FH.png', ['freebird-airlines']);
LogoController::deduplicateLogo('FL.png', []);
LogoController::deduplicateLogo('FM.png', ['shanghai-airlines']);
LogoController::deduplicateLogo('FN.png', ['fastjet-airlines']);
LogoController::deduplicateLogo('FO.png', []);
LogoController::deduplicateLogo('FP.png', []);
LogoController::deduplicateLogo('FR.png', ['ryanair']);
LogoController::deduplicateLogo('FS.png', []);
LogoController::deduplicateLogo('FT.png', []);
LogoController::deduplicateLogo('FU.png', ['fuzhou-airlines']);
LogoController::deduplicateLogo('FV.png', ['rossiya-airlines']);
LogoController::deduplicateLogo('FW.png', ['ibex-airlines']);
LogoController::deduplicateLogo('FX.png', ['federal-express']);
LogoController::deduplicateLogo('FY.png', ['flyfirefly-sdn-bhd']);
LogoController::deduplicateLogo('FZ.png', ['flydubai']);
LogoController::deduplicateLogo('G2.png', []);
LogoController::deduplicateLogo('G3.png', ['gol-airlines']);
LogoController::deduplicateLogo('G8.png', []);
LogoController::deduplicateLogo('GC.png', []);
LogoController::deduplicateLogo('GD.png', []);
LogoController::deduplicateLogo('GE.png', []);
LogoController::deduplicateLogo('GF.png', ['gulf-air']);
LogoController::deduplicateLogo('GH.png', []);
LogoController::deduplicateLogo('GI.png', []);
LogoController::deduplicateLogo('GJ.png', ['zhejiang-loong-airlines']);
LogoController::deduplicateLogo('GK.png', ['jetstar-japan']);
LogoController::deduplicateLogo('GO.png', ['uls-airlines-cargo']);
LogoController::deduplicateLogo('GP.png', []);
LogoController::deduplicateLogo('GQ.png', ['sky-express-s-a']);
LogoController::deduplicateLogo('GR.png', ['aurigny-air-limited']);
LogoController::deduplicateLogo('GS.png', ['tianjin-airlines']);
LogoController::deduplicateLogo('GT.png', ['air-guilin']);
LogoController::deduplicateLogo('GV.png', []);
LogoController::deduplicateLogo('GW.png', []);
LogoController::deduplicateLogo('GX.png', ['guangxi-beibu-gulf-airlines']);
LogoController::deduplicateLogo('GY.png', ['colorful-guizhou-airlines']);
LogoController::deduplicateLogo('GZ.png', ['air-rarotonga']);
LogoController::deduplicateLogo('H1.png', ['hahn-air-systems']);
LogoController::deduplicateLogo('H4.png', []);
LogoController::deduplicateLogo('H5.png', []);
LogoController::deduplicateLogo('H6.png', ['bulgarian-air-charter']);
LogoController::deduplicateLogo('H7.png', []);
LogoController::deduplicateLogo('H8.png', []);
LogoController::deduplicateLogo('H9.png', ['himalaya-airlines-pvt']);
LogoController::deduplicateLogo('HB.png', []);
LogoController::deduplicateLogo('HC.png', []);
LogoController::deduplicateLogo('HD.png', ['air-do']);
LogoController::deduplicateLogo('HE.png', []);
LogoController::deduplicateLogo('HH.png', []);
LogoController::deduplicateLogo('HJ.png', []);
LogoController::deduplicateLogo('HK.png', ['skippers-aviation']);
LogoController::deduplicateLogo('HM.png', ['air-seychelles']);
LogoController::deduplicateLogo('HN.png', []);
LogoController::deduplicateLogo('HO.png', ['juneyao-airlines']);
LogoController::deduplicateLogo('HP.png', []);
LogoController::deduplicateLogo('HQ.png', []);
LogoController::deduplicateLogo('HR.png', ['hahn-air']);
LogoController::deduplicateLogo('HT.png', []);
LogoController::deduplicateLogo('HU.png', ['hainan-airlines']);
LogoController::deduplicateLogo('HV.png', []);
LogoController::deduplicateLogo('HW.png', ['north-wright-airways']);
LogoController::deduplicateLogo('HX.png', ['hong-kong-airlines']);
LogoController::deduplicateLogo('HY.png', ['uzbekistan-airways']);
LogoController::deduplicateLogo('HZ.png', ['joint-stock-aurora-airlines']);
LogoController::deduplicateLogo('I2.png', ['compania-operadora-de-corto-y-medio-radio-iberia-express']);
LogoController::deduplicateLogo('I6.png', []);
LogoController::deduplicateLogo('I8.png', ['izhavia-public-stock']);
LogoController::deduplicateLogo('ID.png', ['pt-batik-air-indonesia']);
LogoController::deduplicateLogo('IF.png', []);
LogoController::deduplicateLogo('IH.png', []);
LogoController::deduplicateLogo('IJ.png', ['spring-airlines-japan', 'spring-japan']);
LogoController::deduplicateLogo('IK.png', []);
LogoController::deduplicateLogo('IL.png', ['pt-trigana-air']);
LogoController::deduplicateLogo('IN.png', ['nam-air']);
LogoController::deduplicateLogo('IO.png', []);
LogoController::deduplicateLogo('IP.png', []);
LogoController::deduplicateLogo('IQ.png', []);
LogoController::deduplicateLogo('IS.png', []);
LogoController::deduplicateLogo('IT.png', ['tigerair-taiwan']);
LogoController::deduplicateLogo('IU.png', []);
LogoController::deduplicateLogo('IV.png', []);
LogoController::deduplicateLogo('IW.png', ['pt-wings-abadi-airlines']);
LogoController::deduplicateLogo('IX.png', []);
LogoController::deduplicateLogo('J1.png', []);
LogoController::deduplicateLogo('J4.png', ['badr-airlines']);
LogoController::deduplicateLogo('J5.png', ['alaska-seaplane', 'alaska-seaplane-j5']);
LogoController::deduplicateLogo('J6.png', ['japan-air-commuter']);
LogoController::deduplicateLogo('J7.png', []);
LogoController::deduplicateLogo('J9.png', ['jazeera-airways']);
LogoController::deduplicateLogo('JA.png', []);
LogoController::deduplicateLogo('JB.png', []);
LogoController::deduplicateLogo('JC.png', ['japan-air-commuter']);
LogoController::deduplicateLogo('JD.png', ['beijing-capital-airlines']);
LogoController::deduplicateLogo('JE.png', ['mango-airlines-soc-trading-as-mango']);
LogoController::deduplicateLogo('JG.png', []);
LogoController::deduplicateLogo('JH.png', ['fuji-dream-airlines']);
LogoController::deduplicateLogo('JI.png', []);
LogoController::deduplicateLogo('JM.png', []);
LogoController::deduplicateLogo('JP.png', []);
LogoController::deduplicateLogo('JQ.png', ['jetstar-airways-pty']);
LogoController::deduplicateLogo('JS.png', ['air-koryo']);
LogoController::deduplicateLogo('JT.png', ['lion-airlines']);
LogoController::deduplicateLogo('JU.png', ['air-serbia-a-d-beograd']);
LogoController::deduplicateLogo('JX.png', []);
LogoController::deduplicateLogo('JY.png', ['intercaribbean-airways']);
LogoController::deduplicateLogo('JZ.png', []);
LogoController::deduplicateLogo('K4.png', []);
LogoController::deduplicateLogo('K6.png', ['cambodia-angkor-air-t-a-cambodia-angkor-air']);
LogoController::deduplicateLogo('K7.png', []);
LogoController::deduplicateLogo('K9.png', []);
LogoController::deduplicateLogo('KA.png', []);
LogoController::deduplicateLogo('KB.png', ['druk-air-corporation']);
LogoController::deduplicateLogo('KC.png', ['air-astana']);
LogoController::deduplicateLogo('KD.png', []);
LogoController::deduplicateLogo('KG.png', []);
LogoController::deduplicateLogo('KK.png', []);
LogoController::deduplicateLogo('KN.png', []);
LogoController::deduplicateLogo('KP.png', []);
LogoController::deduplicateLogo('KQ.png', ['kenya-airways']);
LogoController::deduplicateLogo('KR.png', []);
LogoController::deduplicateLogo('KS.png', []);
LogoController::deduplicateLogo('KT.png', []);
LogoController::deduplicateLogo('KV.png', []);
LogoController::deduplicateLogo('KW.png', []);
LogoController::deduplicateLogo('KY.png', ['kunming-airlines']);
LogoController::deduplicateLogo('KZ.png', ['nippon-cargo-airlines-nca']);
LogoController::deduplicateLogo('L2.png', []);
LogoController::deduplicateLogo('L3.png', ['dhl-de-guatemala-s-a']);
LogoController::deduplicateLogo('L6.png', ['mauritanian-airlines-international']);
LogoController::deduplicateLogo('L7.png', []);
LogoController::deduplicateLogo('L8.png', []);
LogoController::deduplicateLogo('LB.png', []);
LogoController::deduplicateLogo('LC.png', []);
LogoController::deduplicateLogo('LD.png', []);
LogoController::deduplicateLogo('LF.png', []);
LogoController::deduplicateLogo('LH.png', ['lufthansa', 'lufthansa-cargo']);
LogoController::deduplicateLogo('LJ.png', ['jin-air']);
LogoController::deduplicateLogo('LK.png', ['lao-skyway']);
LogoController::deduplicateLogo('LL.png', []);
LogoController::deduplicateLogo('LM.png', ['loganair']);
LogoController::deduplicateLogo('LN.png', ['libyan-airlines']);
LogoController::deduplicateLogo('LP.png', []);
LogoController::deduplicateLogo('LS.png', ['jet2-com']);
LogoController::deduplicateLogo('LU.png', []);
LogoController::deduplicateLogo('LW.png', []);
LogoController::deduplicateLogo('LX.png', ['swiss']);
LogoController::deduplicateLogo('LZ.png', []);
LogoController::deduplicateLogo('M2.png', []);
LogoController::deduplicateLogo('M4.png', ['mistral-air']);
LogoController::deduplicateLogo('M7.png', ['mas-air']);
LogoController::deduplicateLogo('M8.png', []);
LogoController::deduplicateLogo('MB.png', []);
LogoController::deduplicateLogo('MD.png', ['air-madagascar']);
LogoController::deduplicateLogo('MF.png', ['xiamen-airlines']);
LogoController::deduplicateLogo('MG.png', []);
LogoController::deduplicateLogo('MI.png', []);
LogoController::deduplicateLogo('MJ.png', []);
LogoController::deduplicateLogo('ML.png', []);
LogoController::deduplicateLogo('MO.png', ['calm-air-international']);
LogoController::deduplicateLogo('MQ.png', ['envoy-air']);
LogoController::deduplicateLogo('MR.png', ['hunnu-air']);
LogoController::deduplicateLogo('MS.png', ['egyptair']);
LogoController::deduplicateLogo('MT.png', []);
LogoController::deduplicateLogo('MU.png', ['china-eastern']);
LogoController::deduplicateLogo('MV.png', []);
LogoController::deduplicateLogo('MW.png', []);
LogoController::deduplicateLogo('MY.png', []);
LogoController::deduplicateLogo('MZ.png', ['amakusa-airlines']);
LogoController::deduplicateLogo('N2.png', []);
LogoController::deduplicateLogo('N3.png', []);
LogoController::deduplicateLogo('N4.png', ['nord-wind']);
LogoController::deduplicateLogo('N5.png', []);
LogoController::deduplicateLogo('N7.png', []);
LogoController::deduplicateLogo('N8.png', ['national-airlines']);
LogoController::deduplicateLogo('N9.png', []);
LogoController::deduplicateLogo('NA.png', []);
LogoController::deduplicateLogo('NB.png', []);
LogoController::deduplicateLogo('NE.png', ['nesma-airlines']);
LogoController::deduplicateLogo('NF.png', ['air-vanuatu-operations']);
LogoController::deduplicateLogo('NG.png', ['']);
LogoController::deduplicateLogo('NI.png', []);
LogoController::deduplicateLogo('NJ.png', []);
LogoController::deduplicateLogo('NK.png', ['spirit', 'spirit-airlines']);
LogoController::deduplicateLogo('NL.png', []);
LogoController::deduplicateLogo('NM.png', []);
LogoController::deduplicateLogo('NN.png', []);
LogoController::deduplicateLogo('NO.png', []);
LogoController::deduplicateLogo('NP.png', ['nile-air']);
LogoController::deduplicateLogo('NQ.png', []);
LogoController::deduplicateLogo('NR.png', []);
LogoController::deduplicateLogo('NS.png', ['hebei-airlines']);
LogoController::deduplicateLogo('NT.png', ['binter-canarias']);
LogoController::deduplicateLogo('NU.png', []);
LogoController::deduplicateLogo('NX.png', ['air-macau']);
LogoController::deduplicateLogo('NZ.png', ['air-new-zealand']);
LogoController::deduplicateLogo('O9.png', []);
LogoController::deduplicateLogo('OB.png', ['boliviana-de-aviacion-boa']);
LogoController::deduplicateLogo('OC.png', ['oriental-air-bridge']);
LogoController::deduplicateLogo('OD.png', ['malindo-airways-sdn-bhd-malindo-a']);
LogoController::deduplicateLogo('OE.png', []);
LogoController::deduplicateLogo('OF.png', []);
LogoController::deduplicateLogo('OI.png', ['hinterland-aviation-pty']);
LogoController::deduplicateLogo('OJ.png', []);
LogoController::deduplicateLogo('OL.png', []);
LogoController::deduplicateLogo('OP.png', []);
LogoController::deduplicateLogo('OQ.png', ['chongqing-airlines']);
LogoController::deduplicateLogo('OR.png', ['arkefly']);
LogoController::deduplicateLogo('OU.png', ['croatia-airlines']);
LogoController::deduplicateLogo('OV.png', []);
LogoController::deduplicateLogo('OW.png', []);
LogoController::deduplicateLogo('OY.png', []);
LogoController::deduplicateLogo('OZ.png', ['asiana']);
LogoController::deduplicateLogo('P3.png', []);
LogoController::deduplicateLogo('P4.png', []);
LogoController::deduplicateLogo('P7.png', []);
LogoController::deduplicateLogo('P8.png', ['sprintair-sa']);
LogoController::deduplicateLogo('PA.png', ['airblue']);
LogoController::deduplicateLogo('PB.png', []);
LogoController::deduplicateLogo('PC.png', ['pegasus-airlines']);
LogoController::deduplicateLogo('PD.png', ['porter-airlines']);
LogoController::deduplicateLogo('PE.png', []);
LogoController::deduplicateLogo('PF.png', []);
LogoController::deduplicateLogo('PG.png', ['bangkok-air']);
LogoController::deduplicateLogo('PI.png', ['polar-airlines-ojsc']);
LogoController::deduplicateLogo('PJ.png', ['air-saint-pierre']);
LogoController::deduplicateLogo('PL.png', ['southern-air-charter']);
LogoController::deduplicateLogo('PM.png', ['canary-fly']);
LogoController::deduplicateLogo('PN.png', ['china-west-air']);
LogoController::deduplicateLogo('PO.png', ['polar-air-cargo-worldwide']);
LogoController::deduplicateLogo('PQ.png', []);
LogoController::deduplicateLogo('PS.png', ['ukraine-international-airlines']);
LogoController::deduplicateLogo('PT.png', ['piedmont-airlines']);
LogoController::deduplicateLogo('PU.png', ['s-a']);
LogoController::deduplicateLogo('PV.png', []);
LogoController::deduplicateLogo('PW.png', []);
LogoController::deduplicateLogo('PX.png', ['air-niugini']);
LogoController::deduplicateLogo('Q3.png', ['anguilla-air']);
LogoController::deduplicateLogo('Q4.png', []);
LogoController::deduplicateLogo('Q5.png', []);
LogoController::deduplicateLogo('Q6.png', []);
LogoController::deduplicateLogo('Q7.png', []);
LogoController::deduplicateLogo('Q9.png', []);
LogoController::deduplicateLogo('QB.png', ['qeshm-air']);
LogoController::deduplicateLogo('QC.png', []);
LogoController::deduplicateLogo('QG.png', ['pt-citilink-indonesia']);
LogoController::deduplicateLogo('QH.png', []);
LogoController::deduplicateLogo('QK.png', ['jazz-aviation-lp']);
LogoController::deduplicateLogo('QL.png', ['laser-airlines']);
LogoController::deduplicateLogo('QN.png', []);
LogoController::deduplicateLogo('QP.png', []);
LogoController::deduplicateLogo('QQ.png', ['alliance-airlines']);
LogoController::deduplicateLogo('QR.png', ['qatar-airways']);
LogoController::deduplicateLogo('QS.png', ['smartwings']);
LogoController::deduplicateLogo('QT.png', []);
LogoController::deduplicateLogo('QU.png', []);
LogoController::deduplicateLogo('QV.png', ['lao-airlines']);
LogoController::deduplicateLogo('QW.png', ['qingdao-airlines']);
LogoController::deduplicateLogo('QX.png', ['horizon-air-industries']);
LogoController::deduplicateLogo('QZ.png', ['airasia-indonesia']);
LogoController::deduplicateLogo('R3.png', []);
LogoController::deduplicateLogo('R4.png', []);
LogoController::deduplicateLogo('R5.png', ['jordan-aviation']);
LogoController::deduplicateLogo('R6.png', []);
LogoController::deduplicateLogo('R8.png', []);
LogoController::deduplicateLogo('RC.png', ['atlantic-airways']);
LogoController::deduplicateLogo('RD.png', []);
LogoController::deduplicateLogo('RF.png', []);
LogoController::deduplicateLogo('RG.png', ['rotana-jet-aviation-dba-rotana-jet']);
LogoController::deduplicateLogo('RH.png', []);
LogoController::deduplicateLogo('RI.png', []);
LogoController::deduplicateLogo('RK.png', []);
LogoController::deduplicateLogo('RN.png', []);
LogoController::deduplicateLogo('RP.png', []);
LogoController::deduplicateLogo('RQ.png', ['kam-air']);
LogoController::deduplicateLogo('RS.png', []);
LogoController::deduplicateLogo('RT.png', []);
LogoController::deduplicateLogo('RV.png', ['air-canada-rouge']);
LogoController::deduplicateLogo('RW.png', []);
LogoController::deduplicateLogo('RX.png', []);
LogoController::deduplicateLogo('RY.png', ['jiangxi-air-limited-dba-jiangxi-air']);
LogoController::deduplicateLogo('RZ.png', ['servicios-aereos-nacionales-s-a-sansa']);
LogoController::deduplicateLogo('S1.png', ['lufthansa-systems-ag']);
LogoController::deduplicateLogo('S5.png', []);
LogoController::deduplicateLogo('S6.png', ['sunrise-airways-s-a']);
LogoController::deduplicateLogo('S8.png', ['sounds-air-travel-tourism']);
LogoController::deduplicateLogo('SB.png', ['aircalin']);
LogoController::deduplicateLogo('SC.png', ['shandong-airlines']);
LogoController::deduplicateLogo('SE.png', []);
LogoController::deduplicateLogo('SF.png', ['tassili-airlines']);
LogoController::deduplicateLogo('SG.png', ['spicejet']);
LogoController::deduplicateLogo('SH.png', ['sharp-airlines']);
LogoController::deduplicateLogo('SJ.png', ['pt-sriwijaya-air']);
LogoController::deduplicateLogo('SL.png', ['thai-lion-air', 'thai-lion-mentari']);
LogoController::deduplicateLogo('SM.png', ['air-cairo']);
LogoController::deduplicateLogo('SO.png', []);
LogoController::deduplicateLogo('SP.png', ['sata-air-acores']);
LogoController::deduplicateLogo('SQ.png', ['sia-cargo']);
LogoController::deduplicateLogo('SS.png', ['corsair']);
LogoController::deduplicateLogo('ST.png', []);
LogoController::deduplicateLogo('SY.png', []);
LogoController::deduplicateLogo('SZ.png', ['aircompany-somon-air']);
LogoController::deduplicateLogo('T2.png', []);
LogoController::deduplicateLogo('T5.png', ['turkmenistan-airlines']);
LogoController::deduplicateLogo('T6.png', ['island-transvoyager']);
LogoController::deduplicateLogo('T7.png', ['twin-jet']);
LogoController::deduplicateLogo('T9.png', ['turpial']);
LogoController::deduplicateLogo('TA.png', []);
LogoController::deduplicateLogo('TB.png', ['tui-airlines-belgium-t-a-jetairfly']);
LogoController::deduplicateLogo('TC.png', ['air-tanzania-ltd']);
LogoController::deduplicateLogo('TD.png', []);
LogoController::deduplicateLogo('TE.png', ['sky-taxi-sp-z-o-o']);
LogoController::deduplicateLogo('TF.png', ['braathens-regional-aviation-ab']);
LogoController::deduplicateLogo('TH.png', []);
LogoController::deduplicateLogo('TI.png', ['tailwind-hava-yollari-a-s']);
LogoController::deduplicateLogo('TJ.png', ['tradewind-aviation']);
LogoController::deduplicateLogo('TL.png', []);
LogoController::deduplicateLogo('TM.png', ['lam']);
LogoController::deduplicateLogo('TN.png', ['air-tahiti-nui']);
LogoController::deduplicateLogo('TO.png', ['transavia-france']);
LogoController::deduplicateLogo('TR.png', ['scoot-private']);
LogoController::deduplicateLogo('TS.png', ['air-transat']);
LogoController::deduplicateLogo('TT.png', []);
LogoController::deduplicateLogo('TV.png', ['tibet-airlines-corporation']);
LogoController::deduplicateLogo('TW.png', ['t-way-air']);
LogoController::deduplicateLogo('TX.png', ['air-caraibes']);
LogoController::deduplicateLogo('TZ.png', ['tsaradia']);
LogoController::deduplicateLogo('U4.png', ['buddha-air']);
LogoController::deduplicateLogo('U7.png', ['uniworld-air-cargo-corp']);
LogoController::deduplicateLogo('U8.png', ['tus-airways']);
LogoController::deduplicateLogo('UA.png', ['united-airlines']);
LogoController::deduplicateLogo('UB.png', ['myanmar-national-airlines']);
LogoController::deduplicateLogo('UC.png', []);
LogoController::deduplicateLogo('UD.png', []);
LogoController::deduplicateLogo('UF.png', []);
LogoController::deduplicateLogo('UG.png', ['tunisair-express']);
LogoController::deduplicateLogo('UI.png', ['auric-air-limited']);
LogoController::deduplicateLogo('UJ.png', []);
LogoController::deduplicateLogo('UL.png', ['srilankan-airlines']);
LogoController::deduplicateLogo('UM.png', ['air-zimbabwe-pvt']);
LogoController::deduplicateLogo('UN.png', []);
LogoController::deduplicateLogo('UO.png', ['hong-kong-express-airways']);
LogoController::deduplicateLogo('UP.png', ['bahamasair']);
LogoController::deduplicateLogo('UQ.png', ['urumqi-airlines']);
LogoController::deduplicateLogo('UR.png', []);
LogoController::deduplicateLogo('US.png', ['us-airways']);
LogoController::deduplicateLogo('UX.png', ['air-europa']);
LogoController::deduplicateLogo('UY.png', []);
LogoController::deduplicateLogo('UZ.png', ['buraq-air']);
LogoController::deduplicateLogo('V3.png', ['carpatair']);
LogoController::deduplicateLogo('V5.png', []);
LogoController::deduplicateLogo('V6.png', []);
LogoController::deduplicateLogo('V8.png', []);
LogoController::deduplicateLogo('VB.png', ['aeroenlaces-nacionales-s-a-de-c-v']);
LogoController::deduplicateLogo('VC.png', []);
LogoController::deduplicateLogo('VD.png', []);
LogoController::deduplicateLogo('VE.png', []);
LogoController::deduplicateLogo('VF.png', []);
LogoController::deduplicateLogo('VJ.png', ['vietjet-aviation-joint-stock']);
LogoController::deduplicateLogo('VK.png', []);
LogoController::deduplicateLogo('VL.png', []);
LogoController::deduplicateLogo('VM.png', ['max-air']);
LogoController::deduplicateLogo('VN.png', ['vietnam-airlines']);
LogoController::deduplicateLogo('VP.png', ['flyme']);
LogoController::deduplicateLogo('VQ.png', ['novoair']);
LogoController::deduplicateLogo('VS.png', ['virgin-atlantic']);
LogoController::deduplicateLogo('VU.png', []);
LogoController::deduplicateLogo('VV.png', []);
LogoController::deduplicateLogo('VX.png', ['virgin-america']);
LogoController::deduplicateLogo('VY.png', ['vueling']);
LogoController::deduplicateLogo('VZ.png', []);
LogoController::deduplicateLogo('W2.png', ['flexflight-aps']);
LogoController::deduplicateLogo('W3.png', ['arik-air']);
LogoController::deduplicateLogo('W4.png', []);
LogoController::deduplicateLogo('W6.png', ['wizz-air']);
LogoController::deduplicateLogo('W7.png', []);
LogoController::deduplicateLogo('W8.png', ['cargojet-airways']);
LogoController::deduplicateLogo('W9.png', []);
LogoController::deduplicateLogo('WA.png', ['klm-cityhopper']);
LogoController::deduplicateLogo('WB.png', ['rwandair']);
LogoController::deduplicateLogo('WD.png', []);
LogoController::deduplicateLogo('WE.png', []);
LogoController::deduplicateLogo('WH.png', []);
LogoController::deduplicateLogo('WI.png', []);
LogoController::deduplicateLogo('WJ.png', []);
LogoController::deduplicateLogo('WK.png', ['edelweiss-air']);
LogoController::deduplicateLogo('WL.png', []);
LogoController::deduplicateLogo('WN.png', ['southwest-airlines']);
LogoController::deduplicateLogo('WO.png', []);
LogoController::deduplicateLogo('WP.png', []);
LogoController::deduplicateLogo('WR.png', ['westjet-encore']);
LogoController::deduplicateLogo('WS.png', ['westjet']);
LogoController::deduplicateLogo('WT.png', []);
LogoController::deduplicateLogo('WU.png', []);
LogoController::deduplicateLogo('WV.png', []);
LogoController::deduplicateLogo('WW.png', []);
LogoController::deduplicateLogo('WZ.png', ['airlines-400']);
LogoController::deduplicateLogo('X3.png', ['tuifly']);
LogoController::deduplicateLogo('X4.png', []);
LogoController::deduplicateLogo('X5.png', []);
LogoController::deduplicateLogo('X9.png', ['jsc-avion-express']);
LogoController::deduplicateLogo('XC.png', ['corendon-airlines']);
LogoController::deduplicateLogo('XD.png', []);
LogoController::deduplicateLogo('XE.png', []);
LogoController::deduplicateLogo('XF.png', []);
LogoController::deduplicateLogo('XJ.png', ['thai-airasia-x-limited']);
LogoController::deduplicateLogo('XK.png', ['air-corsica']);
LogoController::deduplicateLogo('XL.png', []);
LogoController::deduplicateLogo('XM.png', ['zimex-aviation']);
LogoController::deduplicateLogo('XN.png', []);
LogoController::deduplicateLogo('XO.png', ['south-east-asian-airlines-seair-international']);
LogoController::deduplicateLogo('XP.png', []);
LogoController::deduplicateLogo('XT.png', []);
LogoController::deduplicateLogo('XY.png', ['national-air-dba-flynas']);
LogoController::deduplicateLogo('Y2.png', ['air-century']);
LogoController::deduplicateLogo('Y4.png', ['volaris']);
LogoController::deduplicateLogo('Y5.png', []);
LogoController::deduplicateLogo('Y6.png', ['ab-aviation']);
LogoController::deduplicateLogo('Y7.png', []);
LogoController::deduplicateLogo('YC.png', []);
LogoController::deduplicateLogo('YD.png', []);
LogoController::deduplicateLogo('YE.png', ['yanair']);
LogoController::deduplicateLogo('YI.png', []);
LogoController::deduplicateLogo('YK.png', ['avia-traffic']);
LogoController::deduplicateLogo('YP.png', []);
LogoController::deduplicateLogo('YQ.png', []);
LogoController::deduplicateLogo('YT.png', ['yeti-airlines']);
LogoController::deduplicateLogo('YU.png', ['euroatlantic-airways']);
LogoController::deduplicateLogo('YW.png', ['air-nostrum']);
LogoController::deduplicateLogo('Z2.png', []);
LogoController::deduplicateLogo('Z7.png', []);
LogoController::deduplicateLogo('ZA.png', ['sky-angkor-airlines']);
LogoController::deduplicateLogo('ZE.png', ['eastar-jet']);
LogoController::deduplicateLogo('ZF.png', ['azur-air-liability']);
LogoController::deduplicateLogo('ZG.png', []);
LogoController::deduplicateLogo('ZH.png', ['shenzhen-airlines']);
LogoController::deduplicateLogo('ZL.png', ['rex-regional-express']);
LogoController::deduplicateLogo('ZM.png', ['air-manas-dba-air-manas-air']);
LogoController::deduplicateLogo('ZN.png', []);
LogoController::deduplicateLogo('ZP.png', []);
LogoController::deduplicateLogo('ZQ.png', []);
LogoController::deduplicateLogo('ZT.png', ['titan-airways']);
LogoController::deduplicateLogo('ZV.png', []);
LogoController::deduplicateLogo('ZX.png', []);
LogoController::deduplicateLogo('ZY.png', []);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
@@ -0,0 +1,271 @@
<?php
use App\Models\Airline;
use App\Models\Country;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function createAirline(
string $name,
bool $active,
string $countryCode,
?string $iataCode = null,
?string $icaoCode = null,
?string $logo = null,
?string $internalName = null,
): self {
$country = Country::where('code', $countryCode)->firstOrFail();
$internalName = $internalName ?? $this->generateInternalName($name);
$logo = $logo ?? $iataCode . '.png';
Airline::create([
'IATA_code' => $iataCode,
'ICAO_code' => $icaoCode,
'name' => $name,
'internal_name' => $internalName,
'active' => $active,
'logo' => $logo,
'country_id' => $country->id,
]);
return $this;
}
private function generateInternalName(string $name): string
{
return preg_replace('/[^a-z0-9]+/', '-', strtolower($name));
}
public function up(): void
{
$this
->createAirline(name: 'Air Astra', active: true, countryCode: 'BD', iataCode: '2A', icaoCode: 'AWA') //✅
->createAirline(name: 'CMA CGM Air Cargo', active: true, countryCode: 'FR', iataCode: '2C', icaoCode: 'CMA') //✅
->createAirline(name: 'Eastern Airlines', active: true, countryCode: 'US', iataCode: '2D', icaoCode: 'EAL') //✅
->createAirline(name: 'Azul Conecta', active: true, countryCode: 'BR', iataCode: '2F', icaoCode: 'ACN') //✅
->createAirline(name: 'Maya Island Air', active: true, countryCode: 'BZ', iataCode: '2M', icaoCode: 'MYD') //✅
->createAirline(name: 'NG Eagle', active: true, countryCode: 'NG', iataCode: '2N', icaoCode: 'XLE') //✅
->createAirline(name: 'Sunlight Air', active: true, countryCode: 'PH', iataCode: '2R', icaoCode: 'RLB') //✅
->createAirline(name: 'Southwind Airlines', active: true, countryCode: 'TR', iataCode: '2S', icaoCode: 'STW') //✅
->createAirline(name: 'BermudAir', active: true, countryCode: 'BM', iataCode: '2T', icaoCode: 'BMA') //✅
->createAirline(name: 'World2Fly', active: true, countryCode: 'ES', iataCode: '2W', icaoCode: 'WFL') //✅
->createAirline(name: 'Air Chathams', active: true, countryCode: 'NZ', iataCode: '3C', icaoCode: 'CVA')//✅
->createAirline(name: 'Air Arabia Abu Dhabi', active: true, countryCode: 'AE', iataCode: '3L', icaoCode: 'ADY')//✅
->createAirline(name: 'World2Fly Portugal', active: true, countryCode: 'PT', iataCode: '3P', icaoCode: 'WPT')//✅
->createAirline(name: 'Divi Divi Air', active: true, countryCode: 'CW', iataCode: '3R', icaoCode: 'DVR')//✅
->createAirline(name: 'Smartwings Poland', active: true, countryCode: 'PL', iataCode: '3Z', icaoCode: 'TVP')//✅
->createAirline(name: 'Atsa Airways', active: true, countryCode: 'PE', iataCode: '4A', icaoCode: 'AMP')//✅
->createAirline(name: 'FlyYo', active: true, countryCode: 'RO', iataCode: '4D', icaoCode: 'DIR')//✅
->createAirline(name: 'Freedom Airlines Express', active: true, countryCode: 'KE', iataCode: '4F', icaoCode: 'FDT')//✅
->createAirline(name: 'Freedom Airlines Express Somalia', active: true, countryCode: 'SO', iataCode: '4K', icaoCode: 'SMK', internalName: 'freedom-airlines-express-somalia')//✅
->createAirline(name: 'Air Antilles', active: true, countryCode: 'GP', iataCode: '4I', icaoCode: 'KES')//✅
->createAirline(name: 'Mavi Gok Airlines', active: true, countryCode: 'TR', iataCode: '4M', icaoCode: 'MGH')//✅
->createAirline(name: 'Air Montenegro', active: true, countryCode: 'ME', iataCode: '4O', icaoCode: 'MNE')//✅
->createAirline(name: 'Red Sea Airlines', active: true, countryCode: 'EG', iataCode: '4S', icaoCode: 'RSX')//✅
->createAirline(name: 'Rise Air', active: true, countryCode: 'CA', iataCode: '4T', icaoCode: 'WEW')//✅
->createAirline(name: 'Discover Airlines', active: true, countryCode: 'DE', iataCode: '4Y', icaoCode: 'OCN')//✅
->createAirline(name: 'Lanexang Airways', active: true, countryCode: 'LA', iataCode: '5A', icaoCode: 'LXW')//✅
->createAirline(name: 'Aeromexico Connect', active: true, countryCode: 'MX', iataCode: '5D', icaoCode: 'SLI')//✅
->createAirline(name: 'Shirak Avia', active: true, countryCode: 'AM', iataCode: '5G', icaoCode: 'SHS')//✅
->createAirline(name: 'LIAT Air', active: true, countryCode: 'AG', iataCode: '5L', icaoCode: 'GAO')//✅
->createAirline(name: 'Smartavia', active: true, countryCode: 'RU', iataCode: '5N', icaoCode: 'AUL')//✅
->createAirline(name: 'Smartwings Slovakia', active: true, countryCode: 'SK', iataCode: '6D', icaoCode: 'TVQ')//✅
->createAirline(name: 'Air Anka', active: true, countryCode: 'TR', iataCode: '6K', icaoCode: 'TAH')//✅
->createAirline(name: 'CVSky', active: true, countryCode: 'CV', iataCode: '7B', icaoCode: 'KGF')//✅
->createAirline(name: 'Smartwings Hungary', active: true, countryCode: 'HU', iataCode: '7O', icaoCode: 'TVL')//✅
->createAirline(name: 'AeroDili', active: true, countryCode: 'TL', iataCode: '8G', icaoCode: 'DTL')//✅
->createAirline(name: 'Isles of Scilly Skybus', active: true, countryCode: 'GB', iataCode: '8Y', icaoCode: 'IOS')//✅
->createAirline(name: 'Congo Airways', active: true, countryCode: 'CD', iataCode: '8Z', icaoCode: 'CGA')//✅
->createAirline(name: 'Genghis Khan Airlines', active: true, countryCode: 'CN', iataCode: '9D', icaoCode: 'NMG')//✅
->createAirline(name: 'Sun PhuQuoc', active: true, countryCode: 'VN', iataCode: '9G', icaoCode: 'SPQ')//✅
->createAirline(name: 'Fly Jinnah', active: true, countryCode: 'PK', iataCode: '9P', icaoCode: 'FJL')//✅
->createAirline(name: 'SATENA', active: true, countryCode: 'CO', iataCode: '9R', icaoCode: 'NSE')//✅
->createAirline(name: 'Air Samarkand', active: true, countryCode: 'UZ', iataCode: '9S', icaoCode: 'UZS')//✅
->createAirline(name: 'AnimaWings', active: true, countryCode: 'RO', iataCode: 'A2', icaoCode: 'AWG')//✅
->createAirline(name: 'Azimuth Airlines', active: true, countryCode: 'RU', iataCode: 'A4', icaoCode: 'AZO')//✅
->createAirline(name: 'Air Travel', active: true, countryCode: 'CN', iataCode: 'A6', icaoCode: 'OTC')//✅
->createAirline(name: 'AeroLink Uganda', active: true, countryCode: 'UG', iataCode: 'A8', icaoCode: 'XAU')//✅
->createAirline(name: 'Aruba Airlines', active: true, countryCode: 'AW', iataCode: 'AG', icaoCode: 'ARU')//✅
->createAirline(name: 'Air Juan', active: true, countryCode: 'PH', iataCode: 'AO')//✅
->createAirline(name: 'ITA Airways', active: true, countryCode: 'IT', iataCode: 'AZ', icaoCode: 'ITY', logo: 'AZ_2.png')//✅
->createAirline(name: 'BeOND', active: true, countryCode: 'MV', iataCode: 'B4', icaoCode: 'BYD')//✅
->createAirline(name: 'TUI Airways', active: true, countryCode: 'GB', iataCode: 'BY', icaoCode: 'TOM')//✅
->createAirline(name: 'Uni Air', active: true, countryCode: 'TW', iataCode: 'B7', icaoCode: 'UIA')//✅
->createAirline(name: 'French Bee', active: true, countryCode: 'FR', iataCode: 'BF', icaoCode: 'FBU')//✅
->createAirline(name: 'Pacific Airlines', active: true, countryCode: 'VN', iataCode: 'BL', icaoCode: 'PIC')//✅
->createAirline(name: 'Medsky', active: true, countryCode: 'LY', iataCode: 'BM', icaoCode: 'MNS')//✅
->createAirline(name: 'SkyAlps', active: true, countryCode: 'IT', iataCode: 'BQ', icaoCode: 'SWU')//✅
->createAirline(name: 'Toki Air', active: true, countryCode: 'JP', iataCode: 'BV', icaoCode: 'TOK')//✅
->createAirline(name: 'Bluebird Airways', active: true, countryCode: 'GR', iataCode: 'BZ', icaoCode: 'BBG')//✅
->createAirline(name: 'Centrum Air', active: true, countryCode: 'UZ', iataCode: 'C6', icaoCode: 'MFX')
->createAirline(name: 'Air Belgium', active: false, countryCode: 'BE', iataCode: 'CB', icaoCode: 'ABB')
->createAirline(name: 'Chair Airlines', active: true, countryCode: 'CH', iataCode: 'CS', icaoCode: 'CSW')
->createAirline(name: 'Sunrise Dominicana', active: true, countryCode: 'DO', iataCode: 'D6', icaoCode: 'GCA')
->createAirline(name: 'Daallo Airlines', active: true, countryCode: 'SO', iataCode: 'D9', icaoCode: 'DMQ')
->createAirline(name: 'Cebgo', active: true, countryCode: 'PH', iataCode: 'DG', icaoCode: 'SRQ')
->createAirline(name: 'FlyAden', active: true, countryCode: 'YE', iataCode: 'DH', icaoCode: 'QFF')
->createAirline(name: 'Marabu', active: true, countryCode: 'EE', iataCode: 'DI', icaoCode: 'MBU')
->createAirline(name: 'Sunclass Airlines', active: true, countryCode: 'DK', iataCode: 'DK', icaoCode: 'VKG')
->createAirline(name: 'Arajet', active: true, countryCode: 'DO', iataCode: 'DM', icaoCode: 'DWI')
->createAirline(name: 'Dan Air', active: true, countryCode: 'RO', iataCode: 'DN', icaoCode: 'DNA')
->createAirline(name: 'Alexandria Airlines', active: true, countryCode: 'EG', iataCode: 'DQ', icaoCode: 'KHH')
->createAirline(name: 'Enter Air', active: true, countryCode: 'PL', iataCode: 'E4', icaoCode: 'ENT')
->createAirline(name: 'Iberojet', active: true, countryCode: 'ES', iataCode: 'E9', icaoCode: 'EVE')
->createAirline(name: 'EasyJet Europe', active: true, countryCode: 'AT', iataCode: 'EC', icaoCode: 'EJU')
->createAirline(name: 'ECAIR', active: true, countryCode: 'CG', iataCode: 'EJ', icaoCode: 'EQR')
->createAirline(name: 'Air Dolomiti', active: true, countryCode: 'IT', iataCode: 'EN', icaoCode: 'DLA')
->createAirline(name: 'Fly Angola', active: true, countryCode: 'AO', iataCode: 'EQ')
->createAirline(name: 'Serene Air', active: false, countryCode: 'PK', iataCode: 'ER', icaoCode: 'SEP')
->createAirline(name: 'Avianca Express', active: true, countryCode: 'CO', iataCode: 'EX', icaoCode: 'AVR')
->createAirline(name: 'Flyadeal', active: true, countryCode: 'SA', iataCode: 'F3', icaoCode: 'FAD')
->createAirline(name: 'I-Fly', active: true, countryCode: 'RU', iataCode: 'F7', icaoCode: 'RSY')
->createAirline(name: 'Link Airways', active: true, countryCode: 'AU', iataCode: 'FC', icaoCode: 'FCA')
->createAirline(name: '748 Air Services', active: true, countryCode: 'KE', iataCode: 'FE', icaoCode: 'IHO')
->createAirline(name: 'FlyBondi', active: true, countryCode: 'AR', iataCode: 'FO', icaoCode: 'FBZ')
->createAirline(name: 'FlyPelican', active: true, countryCode: 'AU', iataCode: 'FP', icaoCode: 'FRE')
->createAirline(name: 'FlyArystan', active: true, countryCode: 'KZ', iataCode: 'FS', icaoCode: 'AYN')
->createAirline(name: 'FlyTiwi', active: true, countryCode: 'AU', iataCode: 'FT')
->createAirline(name: 'Guyane Express Fly', active: true, countryCode: 'GF', iataCode: 'G8')
->createAirline(name: 'Nexus Airlines', active: true, countryCode: 'AU', iataCode: 'GD')
->createAirline(name: 'Avianca Guatemala', active: true, countryCode: 'GT', iataCode: 'GU', icaoCode: 'GUG')
->createAirline(name: 'Costa Rica Green Airways', active: true, countryCode: 'CR', iataCode: 'GW', icaoCode: 'CRG')
->createAirline(name: 'HiSky Romania', active: true, countryCode: 'RO', iataCode: 'H4', icaoCode: 'HYS')
->createAirline(name: 'CM Airlines', active: true, countryCode: 'HN', iataCode: 'H5', icaoCode: 'OMT')
->createAirline(name: 'Sky Airline Peru', active: true, countryCode: 'PE', iataCode: 'H8', icaoCode: 'SKX')
->createAirline(name: 'Air Senegal', active: true, countryCode: 'SN', iataCode: 'HC', icaoCode: 'SZN')
->createAirline(name: 'Qanot Sharq', active: true, countryCode: 'UZ', iataCode: 'HH', icaoCode: 'QNT')
->createAirline(name: 'Heston Airlines', active: true, countryCode: 'LT', iataCode: 'HN', icaoCode: 'HST')
->createAirline(name: 'Populair', active: true, countryCode: 'SE', iataCode: 'HP', icaoCode: 'APF')
->createAirline(name: 'IndiaOne Air', active: true, countryCode: 'IN', iataCode: 'I7', icaoCode: 'IOA')
->createAirline(name: 'Fly91', active: true, countryCode: 'IN', iataCode: 'IC', icaoCode: 'GOA')
->createAirline(name: 'Southern Sky Airlines', active: true, countryCode: 'KZ', iataCode: 'IH', icaoCode: 'SRS');
$this
->createAirline(name: 'Air Kiribati', active: true, countryCode: 'KI', iataCode: 'IK', icaoCode: 'AKL')
->createAirline(name: 'IrAero', active: true, countryCode: 'RU', iataCode: 'IO', icaoCode: 'IAE')
->createAirline(name: 'Vietjet Air Qazaqstan', active: true, countryCode: 'KZ', iataCode: 'IQ', icaoCode: 'QAZ')
->createAirline(name: 'Sepehran Airlines', active: true, countryCode: 'IR', iataCode: 'IS', icaoCode: 'SHI')
->createAirline(name: 'Super Air Jet', active: true, countryCode: 'ID', iataCode: 'IU', icaoCode: 'SJV')
->createAirline(name: 'Air India Express', active: true, countryCode: 'IN', iataCode: 'IX', icaoCode: 'AXB')
->createAirline(name: 'Buffalo Airways', active: true, countryCode: 'CA', iataCode: 'J0', icaoCode: 'BFL')
->createAirline(name: 'FlyGabon', active: true, countryCode: 'GA', iataCode: 'J7', icaoCode: 'ABS')
->createAirline(name: 'Armenian Airlines', active: true, countryCode: 'AM', iataCode: 'JI', icaoCode: 'AAG')
->createAirline(name: 'LATAM Brasil', active: true, countryCode: 'BR', iataCode: 'JJ', icaoCode: 'TAM')
->createAirline(name: 'Jambojet', active: true, countryCode: 'KE', iataCode: 'JM', icaoCode: 'JMA')
->createAirline(name: 'Starlux Airlines', active: true, countryCode: 'TW', iataCode: 'JX', icaoCode: 'SJX')
->createAirline(name: 'Mingalar', active: true, countryCode: 'MM', iataCode: 'K7', icaoCode: 'KBZ')
->createAirline(name: 'TezJet', active: true, countryCode: 'KG', iataCode: 'K9', icaoCode: 'TEZ')
->createAirline(name: 'Denver Air Connection', active: true, countryCode: 'US', iataCode: 'KG', icaoCode: 'LYM')
->createAirline(name: 'ASKY Airlines', active: true, countryCode: 'TG', iataCode: 'KP', icaoCode: 'SKK')
->createAirline(name: 'Cambodia Airways', active: true, countryCode: 'KH', iataCode: 'KR', icaoCode: 'KME')
->createAirline(name: 'FlyJaya', active: true, countryCode: 'ID', iataCode: 'KS', icaoCode: 'FHS')
->createAirline(name: 'LATAM', active: true, countryCode: 'CL', iataCode: 'LA', icaoCode: 'LAN', logo: 'LA_2.png')
->createAirline(name: 'Lulutai Airlines', active: true, countryCode: 'TO', iataCode: 'L8', icaoCode: 'TON')
->createAirline(name: 'Contour Airlines', active: true, countryCode: 'US', iataCode: 'LF', icaoCode: 'VTE')
->createAirline(name: 'Level', active: true, countryCode: 'ES', iataCode: 'LL', icaoCode: 'LVL')
->createAirline(name: 'Avianca Costa Rica', active: true, countryCode: 'CR', iataCode: 'LR', icaoCode: 'LRC')
->createAirline(name: 'LJ Air', active: true, countryCode: 'CN', iataCode: 'LT', icaoCode: 'SNG')
->createAirline(name: 'Lauda Europe', active: true, countryCode: 'MT', iataCode: 'LW', icaoCode: 'LDA')
->createAirline(name: 'Eznis Airways', active: false, countryCode: 'MN', iataCode: 'MG', icaoCode: 'EZA')
->createAirline(name: 'Myway Airlines', active: true, countryCode: 'GE', iataCode: 'MJ', icaoCode: 'MYW')
->createAirline(name: 'Air Mediterranean', active: true, countryCode: 'GR', iataCode: 'MV', icaoCode: 'MAR')
->createAirline(name: 'Malta Air', active: true, countryCode: 'MT', iataCode: 'MW', icaoCode: 'MAY')
->createAirline(name: 'Breeze Airways', active: true, countryCode: 'US', iataCode: 'MX', icaoCode: 'MXY')
->createAirline(name: 'AirBorneo', active: true, countryCode: 'MY', iataCode: 'MY', icaoCode: 'MWG')
->createAirline(name: 'Volaris El Salvador', active: true, countryCode: 'SV', iataCode: 'N3', icaoCode: 'VOS')
->createAirline(name: 'Shree Airlines', active: true, countryCode: 'NP', iataCode: 'N9', icaoCode: 'SHA')
->createAirline(name: 'Binani Air', active: true, countryCode: 'NG', iataCode: 'NA', icaoCode: 'BGL')
->createAirline(name: 'Berniq Airways', active: true, countryCode: 'LY', iataCode: 'NB', icaoCode: 'BNL')
->createAirline(name: 'TAP Express', active: true, countryCode: 'PT', iataCode: 'NI', icaoCode: 'PGA')
->createAirline(name: 'Air Moana', active: true, countryCode: 'PF', iataCode: 'NM', icaoCode: 'NTR')
->createAirline(name: 'Neos', active: true, countryCode: 'IT', iataCode: 'NO', icaoCode: 'NOS')
->createAirline(name: 'Air Japan', active: true, countryCode: 'JP', iataCode: 'NQ', icaoCode: 'AJX')
->createAirline(name: 'Manta Air', active: true, countryCode: 'MV', iataCode: 'NR', icaoCode: 'MAV')
->createAirline(name: 'Overland Airways', active: true, countryCode: 'NG', iataCode: 'OF', icaoCode: 'OLA')
->createAirline(name: 'Samoa Airways', active: true, countryCode: 'WS', iataCode: 'OL', icaoCode: 'PAO')
->createAirline(name: 'Passion Air', active: true, countryCode: 'GH', iataCode: 'OP', icaoCode: 'DIG')
->createAirline(name: 'SalamAir', active: true, countryCode: 'OM', iataCode: 'OV', icaoCode: 'OMS')
->createAirline(name: 'Skyward Airlines', active: true, countryCode: 'KE', iataCode: 'OW', icaoCode: 'SEW')
->createAirline(name: 'Air Peace', active: true, countryCode: 'NG', iataCode: 'P4', icaoCode: 'APK')
->createAirline(name: 'Wingo', active: true, countryCode: 'CO', iataCode: 'P5', icaoCode: 'RPB')
->createAirline(name: 'PAL Airlines', active: true, countryCode: 'CA', iataCode: 'PB', icaoCode: 'PVL')
->createAirline(name: "People's", active: true, countryCode: 'AT', iataCode: 'PE', icaoCode: 'PEV')
->createAirline(name: 'AirSial', active: true, countryCode: 'PK', iataCode: 'PF', icaoCode: 'SIF')
->createAirline(name: 'LATAM Paraguay', active: true, countryCode: 'PY', iataCode: 'PZ', icaoCode: 'LAP')
->createAirline(name: 'SkyUp Airlines', active: true, countryCode: 'UA', iataCode: 'PQ', icaoCode: 'SQP')
->createAirline(name: 'SkyUp MT', active: true, countryCode: 'MT', iataCode: 'U5', icaoCode: 'SEU')
->createAirline(name: 'St Barth Commuter', active: true, countryCode: 'BL', iataCode: 'PV', icaoCode: 'SBU')
->createAirline(name: 'Maldivian', active: true, countryCode: 'MV', iataCode: 'Q2', icaoCode: 'DQA')
->createAirline(name: 'Volaris Costa Rica', active: true, countryCode: 'CR', iataCode: 'Q6', icaoCode: 'VOC')
->createAirline(name: 'Green Africa Airways', active: true, countryCode: 'NG', iataCode: 'Q9', icaoCode: 'GWG')
->createAirline(name: 'Camair-Co', active: true, countryCode: 'CM', iataCode: 'QC', icaoCode: 'CRC')
->createAirline(name: 'Bamboo Airways', active: true, countryCode: 'VN', iataCode: 'QH', icaoCode: 'BAV')
->createAirline(name: 'Ibom Air', active: true, countryCode: 'NG', iataCode: 'QI', icaoCode: 'IAN')
->createAirline(name: 'Akasa Air', active: true, countryCode: 'IN', iataCode: 'QP', icaoCode: 'AKJ')
->createAirline(name: 'Yakutia Airlines', active: true, countryCode: 'RU', iataCode: 'R3', icaoCode: 'SYL')
->createAirline(name: 'Rano Air', active: true, countryCode: 'NG', iataCode: 'R4', icaoCode: 'RAN')
->createAirline(name: 'DAT', active: true, countryCode: 'LT', iataCode: 'R6', icaoCode: 'DNU')
->createAirline(name: 'SkyFru', active: true, countryCode: 'KG', iataCode: 'R8', icaoCode: 'KGZ')
->createAirline(name: 'Ryanair UK', active: true, countryCode: 'GB', iataCode: 'RK', icaoCode: 'RUK')
->createAirline(name: 'Eswatini Air', active: true, countryCode: 'SZ', iataCode: 'RN', icaoCode: 'SZL')
->createAirline(name: 'Buzz', active: true, countryCode: 'PL', iataCode: 'RR', icaoCode: 'RYS')
->createAirline(name: 'Air Seoul', active: true, countryCode: 'KR', iataCode: 'RS', icaoCode: 'ASV')
->createAirline(name: 'UVT Aero', active: true, countryCode: 'RU', iataCode: 'RT', icaoCode: 'UVT')
->createAirline(name: 'Riyadh Air', active: true, countryCode: 'SA', iataCode: 'RX', icaoCode: 'RXI')
->createAirline(name: 'Sunrise Airways', active: true, countryCode: 'HT', iataCode: 'S6', icaoCode: 'KSZ')
->createAirline(name: 'Domestic Airlines', active: true, countryCode: 'DZ', iataCode: 'SF', icaoCode: 'DTH')
->createAirline(name: 'Singapore Airlines', active: true, countryCode: 'SG', iataCode: 'SQ', icaoCode: 'SIA')
->createAirline(name: 'Sun Country Airlines', active: true, countryCode: 'US', iataCode: 'SY', icaoCode: 'SCX')
->createAirline(name: 'AirSWIFT', active: true, countryCode: 'PH', iataCode: 'T6', icaoCode: 'ATX')
->createAirline(name: 'Avianca El Salvador', active: true, countryCode: 'SV', iataCode: 'TA', icaoCode: 'TAI')
->createAirline(name: 'Airnorth', active: true, countryCode: 'AU', iataCode: 'TL', icaoCode: 'ANO')
->createAirline(name: 'FlyErbil', active: true, countryCode: 'IQ', iataCode: 'UD', icaoCode: 'UBD')
->createAirline(name: 'Uganda Airlines', active: true, countryCode: 'UG', iataCode: 'UR', icaoCode: 'UGD')
->createAirline(name: 'Umza Air', active: true, countryCode: 'NG', iataCode: 'UY', icaoCode: 'UMZ')
->createAirline(name: 'Aleutian Airways', active: true, countryCode: 'US', iataCode: 'VC', icaoCode: 'SRY')
->createAirline(name: 'Vieques Air Link', active: true, countryCode: 'PR', iataCode: 'VD', icaoCode: 'VES')
->createAirline(name: 'Clic Air', active: true, countryCode: 'CO', iataCode: 'VE', icaoCode: 'EFY')
->createAirline(name: 'Ajet', active: true, countryCode: 'TR', iataCode: 'VF', icaoCode: 'TKJ')
->createAirline(name: 'Valuejet', active: true, countryCode: 'NG', iataCode: 'VK', icaoCode: 'FVJ')
->createAirline(name: 'Lufthansa City Airlines', active: true, countryCode: 'DE', iataCode: 'VL', icaoCode: 'LHX')
->createAirline(name: 'Vietravel Airlines', active: true, countryCode: 'VN', iataCode: 'VU', icaoCode: 'VAG')
->createAirline(name: 'Pattaya Airways', active: true, countryCode: 'TH', iataCode: 'VV', icaoCode: 'PTW')
->createAirline(name: 'Wizz Air Malta', active: true, countryCode: 'MT', iataCode: 'W4', icaoCode: 'WMT')
->createAirline(name: 'Wizz Air UK', active: true, countryCode: 'GB', iataCode: 'W9', icaoCode: 'WUK')
->createAirline(name: 'Wingo Panama', active: true, countryCode: 'PA', iataCode: 'WH', icaoCode: 'WWP')
->createAirline(name: 'Wasaya Airways', active: true, countryCode: 'CA', iataCode: 'WP', icaoCode: 'WSG')
->createAirline(name: 'Western Air', active: true, countryCode: 'BS', iataCode: 'WU', icaoCode: 'WST')
->createAirline(name: 'FlyNamibia', active: true, countryCode: 'NA', iataCode: 'WV', icaoCode: 'FLN')
->createAirline(name: 'Venezolana', active: true, countryCode: 'VE', iataCode: 'WW', icaoCode: 'VNE');
$this
->createAirline(name: 'Air Europa Express', active: true, countryCode: 'ES', iataCode: 'X5', icaoCode: 'OVA')
->createAirline(name: 'JSX', active: true, countryCode: 'US', iataCode: 'XE', icaoCode: 'JSX')
->createAirline(name: 'Mexicana de Aviacion', active: true, countryCode: 'MX', iataCode: 'XN', icaoCode: 'MXA')
->createAirline(name: 'Avelo Airlines', active: true, countryCode: 'US', iataCode: 'XP', icaoCode: 'VXP')
->createAirline(name: 'AeroItalia', active: true, countryCode: 'IT', iataCode: 'XZ', icaoCode: 'AEZ')
->createAirline(name: 'Suparna Airlines', active: true, countryCode: 'CN', iataCode: 'Y8', icaoCode: 'YZR')
->createAirline(name: 'Harbour Air Seaplanes', active: true, countryCode: 'CA', iataCode: 'YB')
->createAirline(name: 'Yamal Airlines', active: true, countryCode: 'RU', iataCode: 'YC', icaoCode: 'LLM')
->createAirline(name: 'Fly OYA', active: true, countryCode: 'LY', iataCode: 'YI', icaoCode: 'OYA')
->createAirline(name: 'Air Premia', active: true, countryCode: 'KR', iataCode: 'YP', icaoCode: 'APZ')
->createAirline(name: 'TAR Aerolineas', active: true, countryCode: 'MX', iataCode: 'YQ', icaoCode: 'LCT')
->createAirline(name: 'FlightLink', active: true, countryCode: 'TZ', iataCode: 'YS', icaoCode: 'FLZ')
->createAirline(name: 'Philippines AirAsia', active: true, countryCode: 'PH', iataCode: 'Z2', icaoCode: 'APG')
->createAirline(name: 'ZIPAIR', active: true, countryCode: 'JP', iataCode: 'ZG', icaoCode: 'TZP')
->createAirline(name: 'Zambia Airways', active: true, countryCode: 'ZM', iataCode: 'ZN', icaoCode: 'AZB')
->createAirline(name: 'Paranair', active: true, countryCode: 'PY', iataCode: 'ZP', icaoCode: 'AZP')
->createAirline(name: 'Aerus', active: true, countryCode: 'MX', iataCode: 'ZV', icaoCode: 'RFD')
;
}
public function down(): void
{
}
};
@@ -0,0 +1,748 @@
<?php
use App\Models\Airline;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Airline::where('internal_name', "748-air-services")->update(['name' => "748 Air Services"]);
Airline::where('internal_name', "ab-aviation")->update(['name' => "AB Aviation"]);
Airline::where('internal_name', "aegean-airlines")->update(['name' => "Aegean Airlines"]);
Airline::where('internal_name', "aer-lingus")->update(['name' => "Aer Lingus"]);
Airline::where('internal_name', "aerodili")->update(['name' => "AeroDili"]);
Airline::where('internal_name', "aeroflot")->update(['name' => "Aeroflot"]);
Airline::where('internal_name', "aeroitalia")->update(['name' => "AeroItalia"]);
Airline::where('internal_name', "aerolineas-argentinas")->update(['name' => "Aerolineas Argentinas"]);
Airline::where('internal_name', "aerogal")->update(['name' => "Avianca Ecuador"]);
Airline::where('internal_name', "aerolink-uganda")->update(['name' => "AeroLink Uganda"]);
Airline::where('internal_name', "aeromexico")->update(['name' => "Aeromexico"]);
Airline::where('internal_name', "aeromexico-connect")->update(['name' => "Aeromexico Connect"]);
Airline::where('internal_name', "aero-mongolia")->update(['name' => "Aero Mongolia"]);
Airline::where('internal_name', "aerotranscargo")->update(['name' => "Aerotranscargo"]);
Airline::where('internal_name', "aerus")->update(['name' => "Aerus"]);
Airline::where('internal_name', "africa-world-airlines")->update(['name' => "Africa World Airlines"]);
Airline::where('internal_name', "afriqiyah-airways")->update(['name' => "Afriqiyah Airways"]);
Airline::where('internal_name', "air-algerie")->update(['name' => "Air Algerie"]);
Airline::where('internal_name', "air-anka")->update(['name' => "Air Anka"]);
Airline::where('internal_name', "air-antilles")->update(['name' => "Air Antilles"]);
Airline::where('internal_name', "air-arabia")->update(['name' => "Air Arabia"]);
Airline::where('internal_name', "air-arabia-abu-dhabi")->update(['name' => "Air Arabia Abu Dhabi"]);
Airline::where('internal_name', "air-arabia-egypt")->update(['name' => "Air Arabia Egypt"]);
Airline::where('internal_name', "air-arabia-maroc")->update(['name' => "Air Arabia Maroc"]);
Airline::where('internal_name', "airasia-berhad-dba-airasia")->update(['name' => "AirAsia"]);
Airline::where('internal_name', "airasia-indonesia")->update(['name' => "AirAsia Indonesia"]);
Airline::where('internal_name', "airasia-x-berhad-dba-airasia-x")->update(['name' => "Air Asia X"]);
Airline::where('internal_name', "airasia-x-malaysia")->delete();
Airline::where('internal_name', "air-astana")->update(['name' => "Air Astana"]);
Airline::where('internal_name', "air-astra")->update(['name' => "Air Astra"]);
Airline::where('internal_name', "air-austral")->update(['name' => "Air Austral"]);
Airline::where('internal_name', "air-baltic")->update(['name' => "Air Baltic"]);
Airline::where('internal_name', "air-belgium")->update(['name' => "Air Belgium"]);
Airline::where('internal_name', "airblue")->update(['name' => "Airblue"]);
Airline::where('internal_name', "airborneo")->update(['name' => "AirBorneo"]);
Airline::where('internal_name', "air-botswana")->update(['name' => "Air Botswana"]);
Airline::where('internal_name', "air-burkina")->update(['name' => "Air Burkina"]);
Airline::where('internal_name', "air-busan")->update(['name' => "Air Busan"]);
Airline::where('internal_name', "air-cairo")->update(['name' => "Air Cairo"]);
Airline::where('internal_name', "air-caledonie")->update(['name' => "Air Caledonie"]);
Airline::where('internal_name', "aircalin")->update(['name' => "Aircalin"]);
Airline::where('internal_name', "air-canada")->update(['name' => "Air Canada"]);
Airline::where('internal_name', "air-canada-rouge")->update(['name' => "Air Canada Rouge"]);
Airline::where('internal_name', "air-caraibes")->update(['name' => "Air Caraibes"]);
Airline::where('internal_name', "air-century")->update(['name' => "Air Century."]);
Airline::where('internal_name', "air-chathams")->update(['name' => "Air Chathams"]);
Airline::where('internal_name', "air-china")->update(['name' => "Air China"]);
Airline::where('internal_name', "air-corsica")->update(['name' => "Air Corsica"]);
Airline::where('internal_name', "air-cote-d-ivoire")->update(['name' => "Air Cote D'Ivoire"]);
Airline::where('internal_name', "air-creebec-1994")->update(['name' => "Air Creebec"]);
Airline::where('internal_name', "air-do")->update(['name' => "Air Do"]);
Airline::where('internal_name', "air-dolomiti")->update(['name' => "Air Dolomiti"]);
Airline::where('internal_name', "air-europa")->update(['name' => "Air Europa"]);
Airline::where('internal_name', "air-europa-express")->update(['name' => "Air Europa Express"]);
Airline::where('internal_name', "airexplore")->update(['name' => "AirExplore"]);
Airline::where('internal_name', "air-france")->update(['name' => "Air France"]);
Airline::where('internal_name', "air-greenland-a-s")->update(['name' => "Air Greenland"]);
Airline::where('internal_name', "air-guilin")->update(['name' => "Air Guilin"]);
Airline::where('internal_name', "air-india")->update(['name' => "Air India"]);
Airline::where('internal_name', "air-india-express")->update(['name' => "Air India Express"]);
Airline::where('internal_name', "air-inuit-ltd-ltee")->update(['name' => "Air Inuit"]);
Airline::where('internal_name', "air-japan")->update(['name' => "Air Japan"]);
Airline::where('internal_name', "air-juan")->update(['name' => "Air Juan"]);
Airline::where('internal_name', "airkenya-express")->update(['name' => "AirKenya Express"]);
Airline::where('internal_name', "air-kiribati")->update(['name' => "Air Kiribati"]);
Airline::where('internal_name', "air-koryo")->update(['name' => "Air Koryo"]);
Airline::where('internal_name', "airline-allied-limited-dba-alliance-air")->update(['name' => "Alliance Air"]);
Airline::where('internal_name', "airlines-of-papua-new-guinea")->update(['name' => "PNG Air"]);
Airline::where('internal_name', "airlink")->update(['name' => "Airlink"]);
Airline::where('internal_name', "air-macau")->update(['name' => "Air Macau"]);
Airline::where('internal_name', "air-madagascar")->update(['name' => "Air Madagascar"]);
Airline::where('internal_name', "air-malta")->update(['name' => "Air Malta"]);
Airline::where('internal_name', "air-manas-dba-air-manas-air")->update(['name' => "Air Manas"]);
Airline::where('internal_name', "air-mauritius")->update(['name' => "Air Mauritius"]);
Airline::where('internal_name', "air-mediterranean")->update(['name' => "Air Mediterranean"]);
Airline::where('internal_name', "air-moana")->update(['name' => "Air Moana"]);
Airline::where('internal_name', "air-montenegro")->update(['name' => "Air Montenegro"]);
Airline::where('internal_name', "air-new-zealand")->update(['name' => "Air New Zealand"]);
Airline::where('internal_name', "air-niugini")->update(['name' => "Air Niugini"]);
Airline::where('internal_name', "airnorth")->update(['name' => "Airnorth"]);
Airline::where('internal_name', "air-north-charter-and-training")->update(['name' => "Air North"]);
Airline::where('internal_name', "air-nostrum")->update(['name' => "Air Nostrum"]);
Airline::where('internal_name', "air-panama-dba-parsa")->update(['name' => "Air Panama"]);
Airline::where('internal_name', "air-peace")->update(['name' => "Air Peace"]);
Airline::where('internal_name', "air-philippines-corporation-dba-pal-express-and-airphil-express")->update(['name' => "PAL Express"]);
Airline::where('internal_name', "air-premia")->update(['name' => "Air Premia"]);
Airline::where('internal_name', "air-rarotonga")->update(['name' => "Air Rarotonga"]);
Airline::where('internal_name', "air-saint-pierre")->update(['name' => "Air Saint-Pierre"]);
Airline::where('internal_name', "air-samarkand")->update(['name' => "Air Samarkand"]);
Airline::where('internal_name', "air-senegal")->update(['name' => "Air Senegal"]);
Airline::where('internal_name', "air-seoul")->update(['name' => "Air Seoul"]);
Airline::where('internal_name', "air-serbia-a-d-beograd")->update(['name' => "AirSERBIA"]);
Airline::where('internal_name', "air-seychelles")->update(['name' => "Air Seychelles"]);
Airline::where('internal_name', "airsial")->update(['name' => "AirSial"]);
Airline::where('internal_name', "airswift")->update(['name' => "AirSWIFT"]);
Airline::where('internal_name', "air-tahiti")->update(['name' => "Air Tahiti"]);
Airline::where('internal_name', "air-tahiti-nui")->update(['name' => "Air Tahiti Nui"]);
Airline::where('internal_name', "air-tanzania-ltd")->update(['name' => "Air Tanzania"]);
Airline::where('internal_name', "air-tindi-8t")->update(['name' => "Air Tindi"]);
Airline::where('internal_name', "air-transat")->update(['name' => "Air Transat"]);
Airline::where('internal_name', "air-travel")->update(['name' => "Air Travel"]);
Airline::where('internal_name', "air-urga")->update(['name' => "Air Urga"]);
Airline::where('internal_name', "air-vanuatu-operations")->update(['name' => "Air Vanuatu"]);
Airline::where('internal_name', "air-wisconsin-airlines-corporation-awac")->update(['name' => "Air Wisconsin"]);
Airline::where('internal_name', "air-zimbabwe-pvt")->update(['name' => "Air Zimbabwe "]);
Airline::where('internal_name', "ajet")->update(['name' => "AJet"]);
Airline::where('internal_name', "akasa-air")->update(['name' => "Akasa Air"]);
Airline::where('internal_name', "aklak")->update(['name' => "Aklak Air"]);
Airline::where('internal_name', "alaska-airlines")->update(['name' => "Alaska Airlines"]);
Airline::where('internal_name', "alaska-seaplane")->update(['name' => "Alaska Seaplane Service"]);
Airline::where('internal_name', "alaska-seaplane-j5")->delete();
Airline::where('internal_name', "aleutian-airways")->update(['name' => "Aleutian Airways"]);
Airline::where('internal_name', "alexandria-airlines")->update(['name' => "Alexandria Airlines"]);
Airline::where('internal_name', "alitalia")->update(['name' => "Alitalia"]);
Airline::where('internal_name', "allegiant-air")->update(['name' => "Allegiant Air LLC"]);
Airline::where('internal_name', "alliance-airlines")->update(['name' => "Alliance Airlines"]);
Airline::where('internal_name', "all-nippon-airways")->update(['name' => "All Nippon Airways"]);
Airline::where('internal_name', "alrosa-air")->update(['name' => "Alrosa Air"]);
Airline::where('internal_name', "alrosa-mirny-air-enterprise")->delete();
Airline::where('internal_name', "alsa-grupo-slu")->delete();
Airline::where('internal_name', "amakusa-airlines")->update(['name' => "Amakusa Airlines"]);
Airline::where('internal_name', "american-airlines")->update(['name' => "American Airlines"]);
Airline::where('internal_name', "ana-wings")->update(['name' => "ANA Wings"]);
Airline::where('internal_name', "anguilla-air")->update(['name' => "Anguilla Air Services"]);
Airline::where('internal_name', "animawings")->update(['name' => "AnimaWings"]);
Airline::where('internal_name', "arajet")->update(['name' => "Arajet"]);
Airline::where('internal_name', "ariana-afghan-airlines")->update(['name' => "Ariana Afghan Airlines"]);
Airline::where('internal_name', "arik-air")->update(['name' => "Arik Air"]);
Airline::where('internal_name', "arkia-israeli-airlines")->update(['name' => "Arkia"]);
Airline::where('internal_name', "armenia-airways-aircompany-cjsc")->update(['name' => "Armenia Airways"]);
Airline::where('internal_name', "armenian-airlines")->update(['name' => "Armenian Airlines"]);
Airline::where('internal_name', "aruba-airlines")->update(['name' => "Aruba Airlines"]);
Airline::where('internal_name', "asiana")->update(['name' => "Asiana"]);
Airline::where('internal_name', "asky-airlines")->update(['name' => "ASKY Airlines"]);
Airline::where('internal_name', "atlantic-airways")->update(['name' => "Atlantic Airways"]);
Airline::where('internal_name', "atlas-air")->update(['name' => "Atlas Air"]);
Airline::where('internal_name', "atsa-airways")->update(['name' => "Atsa Airways"]);
Airline::where('internal_name', "auric-air-limited")->update(['name' => "Auric Air"]);
Airline::where('internal_name', "aurigny-air-limited")->update(['name' => "Aurigny"]);
Airline::where('internal_name', "austrian")->update(['name' => "Austrian"]);
Airline::where('internal_name', "avelo-airlines")->update(['name' => "Avelo Airlines"]);
Airline::where('internal_name', "avianca")->update(['name' => "AVIANCA"]);
Airline::where('internal_name', "avianca-costa-rica")->update(['name' => "Avianca Costa Rica"]);
Airline::where('internal_name', "avianca-el-salvador")->update(['name' => "Avianca El Salvador"]);
Airline::where('internal_name', "avianca-express")->update(['name' => "Avianca Express"]);
Airline::where('internal_name', "avianca-guatemala")->update(['name' => "Avianca Guatemala"]);
Airline::where('internal_name', "avia-traffic")->update(['name' => "Avia Traffic Company"]);
Airline::where('internal_name', "c-a")->update(['name' => "Avior Airlines"]);
Airline::where('internal_name', "azerbaijan-airlines")->update(['name' => "Azerbaijan Airlines"]);
Airline::where('internal_name', "azimuth-airlines")->update(['name' => "Azimuth Airlines"]);
Airline::where('internal_name', "aztec-worldwide-airlines")->update(['name' => "Aztec Airways"]);
Airline::where('internal_name', "azul-brazilian-airlines")->update(['name' => "Azul Brazilian Airlines"]);
Airline::where('internal_name', "azul-conecta")->update(['name' => "Azul Conecta"]);
Airline::where('internal_name', "azur-air-liability")->update(['name' => "Azure Air"]);
Airline::where('internal_name', "ba-cityflyer")->update(['name' => "BA CityFlyer"]);
Airline::where('internal_name', "badr-airlines")->update(['name' => "Badr Airlines"]);
Airline::where('internal_name', "bahamasair")->update(['name' => "Bahamasair"]);
Airline::where('internal_name', "bamboo-airways")->update(['name' => "Bamboo Airways"]);
Airline::where('internal_name', "bangkok-air")->update(['name' => "Bangkok Air"]);
Airline::where('internal_name', "bearskin-lake-air-lp")->update(['name' => "Bearskin Airlines"]);
Airline::where('internal_name', "belavia-belarusian-airlines")->update(['name' => "Belavia"]);
Airline::where('internal_name', "beond")->update(['name' => "BeOND"]);
Airline::where('internal_name', "bering-air")->update(['name' => "Bering Air"]);
Airline::where('internal_name', "berjaya-air-sdn-bhd")->update(['name' => "Berjaya Air"]);
Airline::where('internal_name', "bermudair")->update(['name' => "BermudAir"]);
Airline::where('internal_name', "berniq-airways")->update(['name' => "Berniq Airways"]);
Airline::where('internal_name', "bh-air")->update(['name' => "BH AIR"]);
Airline::where('internal_name', "bhutan-airlines")->update(['name' => "Bhutan Airlines"]);
Airline::where('internal_name', "biman")->update(['name' => "Biman"]);
Airline::where('internal_name', "binani-air")->update(['name' => "Binani Air"]);
Airline::where('internal_name', "binter-canarias")->update(['name' => "Binter Canarias"]);
Airline::where('internal_name', "bluebird-airways")->update(['name' => "Bluebird Airways"]);
Airline::where('internal_name', "boliviana-de-aviacion-boa")->update(['name' => "Boliviana de Aviacion"]);
Airline::where('internal_name', "bonza")->update(['name' => "Bonza"]);
Airline::where('internal_name', "boutique-air")->update(['name' => "Boutique Air"]);
Airline::where('internal_name', "braathens-regional-aviation-ab")->update(['name' => "Braathens Regional Airlines"]);
Airline::where('internal_name', "breeze-airways")->update(['name' => "Breeze Airways"]);
Airline::where('internal_name', "british-airways")->update(['name' => "British Airways"]);
Airline::where('internal_name', "brussels-airlines")->update(['name' => "Brussels Airlines"]);
Airline::where('internal_name', "buddha-air")->update(['name' => "Buddha Air"]);
Airline::where('internal_name', "buffalo-airways")->update(['name' => "Buffalo Airways"]);
Airline::where('internal_name', "bulgaria-air")->update(['name' => "Bulgaria Air"]);
Airline::where('internal_name', "bulgarian-air-charter")->update(['name' => "European Air Charter"]);
Airline::where('internal_name', "buraq-air")->update(['name' => "Buraq Air"]);
Airline::where('internal_name', "buzz")->update(['name' => "Buzz"]);
Airline::where('internal_name', "caicos-express-airways")->update(['name' => "Caicos Express Airways"]);
Airline::where('internal_name', "calm-air-international")->update(['name' => "Calm Air"]);
Airline::where('internal_name', "camair-co")->update(['name' => "Camair-Co"]);
Airline::where('internal_name', "cambodia-airways")->update(['name' => "Cambodia Airways"]);
Airline::where('internal_name', "cambodia-angkor-air-t-a-cambodia-angkor-air")->update(['name' => "Air Cambodia"]);
Airline::where('internal_name', "canadian-north")->update(['name' => "Canadian North"]);
Airline::where('internal_name', "canary-fly")->update(['name' => "Canary Fly"]);
Airline::where('internal_name', "cape-air")->update(['name' => "Cape Air"]);
Airline::where('internal_name', "beijing-capital-airlines")->update(['name' => "Capital Airlines"]);
Airline::where('internal_name', "cargojet-airways")->update(['name' => "Cargojet Airways"]);
Airline::where('internal_name', "cargolux-italia-s-p-a")->update(['name' => "Cargolux Italia"]);
Airline::where('internal_name', "cargolux-s-a")->update(['name' => "Cargolux"]);
Airline::where('internal_name', "caribbean-airlines")->update(['name' => "Caribbean Airlines"]);
Airline::where('internal_name', "carpatair")->update(['name' => "Carpatair"]);
Airline::where('internal_name', "cathay-pacific")->update(['name' => "Cathay Pacific"]);
Airline::where('internal_name', "cayman-airways")->update(['name' => "Cayman Airways"]);
Airline::where('internal_name', "cebgo")->update(['name' => "Cebgo"]);
Airline::where('internal_name', "cebu-pacific-air")->update(['name' => "Cebu Pacific"]);
Airline::where('internal_name', "cemair")->update(['name' => "Cemair"]);
Airline::where('internal_name', "centrum-air")->update(['name' => "Centrum Air"]);
Airline::where('internal_name', "chair-airlines")->update(['name' => "Chair Airlines"]);
Airline::where('internal_name', "chalair-aviation")->update(['name' => "Chalair Aviation"]);
Airline::where('internal_name', "commutair")->update(['name' => "CommuteAir"]);
Airline::where('internal_name', "chang-an-airlines")->update(['name' => "Air Changan"]);
Airline::where('internal_name', "chengdu-airlines")->update(['name' => "Chengdu Airlines"]);
Airline::where('internal_name', "china-airlines")->update(['name' => "China Airlines"]);
Airline::where('internal_name', "china-eastern")->update(['name' => "China Eastern"]);
Airline::where('internal_name', "china-express-airlines")->update(['name' => "China Express Airlines"]);
Airline::where('internal_name', "china-postal-airlines")->update(['name' => "China Postal Airlines"]);
Airline::where('internal_name', "china-southern-airlines")->update(['name' => "China Southern Airlines"]);
Airline::where('internal_name', "china-west-air")->update(['name' => "China West Air"]);
Airline::where('internal_name', "chongqing-airlines")->update(['name' => "Chongqing Airlines"]);
Airline::where('internal_name', "cinnamon-air")->update(['name' => "Cinnamon Air"]);
Airline::where('internal_name', "clic-air")->update(['name' => "Clic Air"]);
Airline::where('internal_name', "cma-cgm-air-cargo")->update(['name' => "CMA CGM Air Cargo"]);
Airline::where('internal_name', "cm-airlines")->update(['name' => "CM Airlines"]);
Airline::where('internal_name', "coastal-aviation")->update(['name' => "Coastal Air"]);
Airline::where('internal_name', "coastal-travels-cq")->delete();
Airline::where('internal_name', "colorful-guizhou-airlines")->update(['name' => "Colorful Guizhou Airlines"]);
Airline::where('internal_name', "compagnie-africaine-d-aviation-caa")->update(['name' => "Compagnie Africaine d'Aviation"]);
Airline::where('internal_name', "compania-operadora-de-corto-y-medio-radio-iberia-express")->update(['name' => "Iberia Express"]);
Airline::where('internal_name', "condor")->update(['name' => "Condor"]);
Airline::where('internal_name', "congo-airways")->update(['name' => "Congo Airways"]);
Airline::where('internal_name', "continental-airlines")->update(['name' => "Continental Airlines"]);
Airline::where('internal_name', "contour-airlines")->update(['name' => "Contour Airlines"]);
Airline::where('internal_name', "conviasa")->update(['name' => "Conviasa"]);
Airline::where('internal_name', "copa-airlines")->update(['name' => "COPA Airlines"]);
Airline::where('internal_name', "corendon-airlines")->update(['name' => "Corendon Airlines"]);
Airline::where('internal_name', "corendon-dutch-airlines-b-v")->update(['name' => "Corendon Dutch Airlines"]);
Airline::where('internal_name', "corsair")->update(['name' => "Corsair International"]);
Airline::where('internal_name', "costa-rica-green-airways")->update(['name' => "Costa Rica Green Airways"]);
Airline::where('internal_name', "croatia-airlines")->update(['name' => "Croatia Airlines"]);
Airline::where('internal_name', "cubana")->update(['name' => "Cubana"]);
Airline::where('internal_name', "cvsky")->update(['name' => "CVSky"]);
Airline::where('internal_name', "cyprus-airways")->update(['name' => "Cyprus Airways"]);
Airline::where('id', 650)->update(['name' => "Daallo Airlines"]);
Airline::where('id', 13199)->update(['name' => "Daallo Airlines Somalia", 'internal_name' => 'daallo-airlines-somalia']);
Airline::where('internal_name', "dan-air")->update(['name' => "Dan Air"]);
Airline::where('internal_name', "danish-air-transport")->update(['name' => "DAT"]);
Airline::where('internal_name', "dat")->update(['name' => "DAT LT"]);
Airline::where('internal_name', "delta-air-lines")->update(['name' => "Delta"]);
Airline::where('internal_name', "denver-air-connection")->update(['name' => "Denver Air Connection"]);
Airline::where('internal_name', "dhl-aero-expreso-s-a")->update(['name' => "DHL Aero Expreso"]);
Airline::where('internal_name', "dhl-air")->update(['name' => "DHL Air"]);
Airline::where('internal_name', "dhl-de-guatemala-s-a")->update(['name' => "DHL de Guatemala"]);
Airline::where('internal_name', "discover-airlines")->update(['name' => "Discover Airlines"]);
Airline::where('internal_name', "divi-divi-air")->update(['name' => "Divi Divi Air"]);
Airline::where('internal_name', "domestic-airlines")->update(['name' => "Domestic Airlines"]);
Airline::where('internal_name', "donghai-airlines")->update(['name' => "Donghai Airlines"]);
Airline::where('internal_name', "dreamjet-sas-t-a-la-compagnie")->update(['name' => "La Compagnie"]);
Airline::where('internal_name', "druk-air-corporation")->update(['name' => "Druk Air"]);
Airline::where('internal_name', "eastar-jet")->update(['name' => "Eastar Jet "]);
Airline::where('internal_name', "eastern-airlines")->update(['name' => "Eastern Airlines"]);
Airline::where('internal_name', "easyjet")->update(['name' => "EasyJet"]);
Airline::where('internal_name', "easyjet-europe")->update(['name' => "EasyJet Europe"]);
Airline::where('internal_name', "easyjet-switzerland-s-a")->update(['name' => "EasyJet Switzerland"]);
Airline::where('internal_name', "ecair")->update(['name' => "ECAIR"]);
Airline::where('internal_name', "edelweiss-air")->update(['name' => "Edelweiss Air"]);
Airline::where('internal_name', "egyptair")->update(['name' => "Egyptair"]);
Airline::where('internal_name', "el-al-israel-airlines")->update(['name' => "EL AL"]);
Airline::where('internal_name', "emirates")->update(['name' => "Emirates"]);
Airline::where('internal_name', "endeavor-air")->update(['name' => "Endeavor Air"]);
Airline::where('internal_name', "enter-air")->update(['name' => "Enter Air"]);
Airline::where('internal_name', "envoy-air")->update(['name' => "Envoy Air Inc."]);
Airline::where('internal_name', "eswatini-air")->update(['name' => "Eswatini Air"]);
Airline::where('internal_name', "ethiopian-airlines")->update(['name' => "Ethiopian Airlines"]);
Airline::where('internal_name', "etihad-airways")->update(['name' => "Etihad Airways"]);
Airline::where('internal_name', "euroatlantic-airways")->update(['name' => "Euroatlantic Airways"]);
Airline::where('internal_name', "eurowings")->update(['name' => "Eurowings"]);
Airline::where('internal_name', "eurowings-europe-gmbh")->update(['name' => "Eurowings Europe"]);
Airline::where('internal_name', "eva-air")->update(['name' => "EVA Air"]);
Airline::where('internal_name', "ewa-air")->update(['name' => "EWA Air"]);
Airline::where('internal_name', "eznis-airways")->update(['name' => "Eznis Airways"]);
Airline::where('internal_name', "fai-rent-a-jet")->delete();
Airline::where('internal_name', "faso-airways")->delete();
Airline::where('internal_name', "fastjet-airlines")->update(['name' => "fastjet"]);
Airline::where('internal_name', "federal-air")->update(['name' => "Federal Air"]);
Airline::where('internal_name', "federal-express")->update(['name' => "Federal Express"]);
Airline::where('internal_name', "air-pacific")->update(['name' => "Fiji Airways"]);
Airline::where('internal_name', "finnair")->update(['name' => "Finnair"]);
Airline::where('internal_name', "fitsair")->update(['name' => "FitsAir"]);
Airline::where('internal_name', "flair-airlines")->update(['name' => "Flair Airlines"]);
Airline::where('internal_name', "flexflight-aps")->update(['name' => "FlexFlight"]);
Airline::where('internal_name', "flightlink")->update(['name' => "FlightLink"]);
Airline::where('internal_name', "fly91")->update(['name' => "Fly91"]);
Airline::where('internal_name', "flyadeal")->update(['name' => "Flyadeal"]);
Airline::where('internal_name', "flyaden")->update(['name' => "FlyAden"]);
Airline::where('internal_name', "fly-all-ways")->update(['name' => "Fly All Ways"]);
Airline::where('internal_name', "fly-always-n-v")->delete();
Airline::where('internal_name', "fly-angola")->update(['name' => "Fly Angola"]);
Airline::where('internal_name', "flyarystan")->update(['name' => "FlyArystan"]);
Airline::where('internal_name', "flybondi")->update(['name' => "FlyBondi"]);
Airline::where('internal_name', "flydubai")->update(['name' => "flydubai"]);
Airline::where('internal_name', "flyerbil")->update(['name' => "FlyErbil"]);
Airline::where('internal_name', "flyexcellent")->delete();
Airline::where('internal_name', "flyfirefly-sdn-bhd")->update(['name' => "Firefly"]);
Airline::where('internal_name', "flygabon")->update(['name' => "FlyGabon"]);
Airline::where('internal_name', "flyjaya")->update(['name' => "FlyJaya"]);
Airline::where('internal_name', "fly-jinnah")->update(['name' => "Fly Jinnah"]);
Airline::where('internal_name', "flynamibia")->update(['name' => "FlyNamibia"]);
Airline::where('internal_name', "fly-one-s-r-l")->update(['name' => "Fly One"]);
Airline::where('internal_name', "fly-oya")->update(['name' => "Fly OYA"]);
Airline::where('internal_name', "flypelican")->update(['name' => "FlyPelican"]);
Airline::where('internal_name', "flytiwi")->update(['name' => "FlyTiwi"]);
Airline::where('internal_name', "flyyo")->update(['name' => "FlyYo"]);
Airline::where('internal_name', "freebird-airlines")->update(['name' => "Freebird Airlines"]);
Airline::where('internal_name', "freedom-airlines-express")->update(['name' => "Freedom Airlines Express"]);
Airline::where('internal_name', "freedom-airlines-express-somalia")->update(['name' => "Freedom Airlines Express Somalia"]);
Airline::where('internal_name', "french-bee")->update(['name' => "French Bee"]);
Airline::where('internal_name', "frontier")->update(['name' => "Frontier"]);
Airline::where('internal_name', "frontier-airlines")->delete();
Airline::where('internal_name', "fuji-dream-airlines")->update(['name' => "Fuji Dream Airlines"]);
Airline::where('internal_name', "fuzhou-airlines")->update(['name' => "Fuzhou Airlines"]);
Airline::where('internal_name', "garuda")->update(['name' => "Garuda Indonesia"]);
Airline::where('internal_name', "gazpromavia-aviation-ltd")->update(['name' => "Gazpromavia"]);
Airline::where('internal_name', "genghis-khan-airlines")->update(['name' => "Genghis Khan Airlines"]);
Airline::where('internal_name', "georgian-airways")->update(['name' => "Georgian Airways"]);
Airline::where('internal_name', "gol-airlines")->update(['name' => "GOL Airlines"]);
Airline::where('internal_name', "grand-canyon-airlines")->update(['name' => "Grand Canyon Scenic Airlines"]);
Airline::where('internal_name', "grand-china-air")->update(['name' => "Grand China Air"]);
Airline::where('internal_name', "green-africa-airways")->update(['name' => "Green Africa Airways"]);
Airline::where('internal_name', "guangxi-beibu-gulf-airlines")->update(['name' => "GX Airlines"]);
Airline::where('internal_name', "gulf-air")->update(['name' => "Gulf Air"]);
Airline::where('internal_name', "guyane-express-fly")->update(['name' => "Guyane Express Fly"]);
Airline::where('internal_name', "hahn-air")->update(['name' => "Hahn Air"]);
Airline::where('internal_name', "hahn-air-systems")->update(['name' => "Hahn Air Systems"]);
Airline::where('internal_name', "hainan-airlines")->update(['name' => "Hainan Airlines"]);
Airline::where('internal_name', "harbour-air-seaplanes")->update(['name' => "Harbour Air Seaplanes"]);
Airline::where('internal_name', "hawaiian-airlines")->update(['name' => "Hawaiian Airlines"]);
Airline::where('internal_name', "hebei-airlines")->update(['name' => "Hebei Airlines"]);
Airline::where('internal_name', "helvetic-airways-ag")->update(['name' => "Helvetic Airways"]);
Airline::where('internal_name', "heston-airlines")->update(['name' => "Heston Airlines"]);
Airline::where('internal_name', "himalaya-airlines-pvt")->update(['name' => "Himalaya Airlines"]);
Airline::where('internal_name', "hinterland-aviation-pty")->update(['name' => "Hinterland Aviation"]);
Airline::where('internal_name', "hisky-romania")->update(['name' => "HiSky Romania"]);
Airline::where('internal_name', "hong-kong-airlines")->update(['name' => "Hong Kong Airlines"]);
Airline::where('internal_name', "hong-kong-express-airways")->update(['name' => "Hong Kong Express Airways"]);
Airline::where('internal_name', "hop")->update(['name' => "HOP!"]);
Airline::where('internal_name', "horizon-air-industries")->update(['name' => "Horizon Air"]);
Airline::where('internal_name', "hunnu-air")->update(['name' => "Hunnu Air"]);
Airline::where('internal_name', "iberia")->update(['name' => "Iberia"]);
Airline::where('internal_name', "iberojet")->update(['name' => "Iberojet"]);
Airline::where('internal_name', "ibex-airlines")->update(['name' => "Ibex Airlines"]);
Airline::where('internal_name', "ibom-air")->update(['name' => "Ibom Air"]);
Airline::where('internal_name', "icelandair")->update(['name' => "Icelandair"]);
Airline::where('internal_name', "i-fly")->update(['name' => "I-Fly"]);
Airline::where('internal_name', "indiaone-air")->update(['name' => "IndiaOne Air"]);
Airline::where('internal_name', "inselair")->update(['name' => "InselAir"]);
Airline::where('internal_name', "intercaribbean-airways")->update(['name' => "InterCaribbean Airways"]);
Airline::where('internal_name', "interglobe-aviation-dba-indigo")->update(['name' => "IndiGo"]);
Airline::where('internal_name', "iraero")->update(['name' => "IrAero"]);
Airline::where('internal_name', "iran-air")->update(['name' => "Iran Air"]);
Airline::where('internal_name', "iran-air-tours")->update(['name' => "Iran Air Tour"]);
Airline::where('internal_name', "iran-aseman-airlines")->update(['name' => "Iran Aseman Airlines"]);
Airline::where('internal_name', "iraqi-airways")->update(['name' => "Iraqi Airways"]);
Airline::where('internal_name', "island-transvoyager")->delete();
Airline::where('internal_name', "isles-of-scilly-skybus")->update(['name' => "Isles of Scilly Skybus"]);
Airline::where('internal_name', "israir")->update(['name' => "Israir"]);
Airline::where('internal_name', "ita-airways")->update(['name' => "ITA Airways"]);
Airline::where('internal_name', "izhavia-public-stock")->update(['name' => "Izhavia"]);
Airline::where('internal_name', "jambojet")->update(['name' => "Jambojet"]);
Airline::where('internal_name', "japan-air-commuter")->update(['name' => "Japan Air Commuter"]);
Airline::where('internal_name', "japan-airlines")->update(['name' => "Japan Airlines"]);
Airline::where('internal_name', "jazeera-airways")->update(['name' => "Jazeera Airways"]);
Airline::where('internal_name', "jazz-aviation-lp")->update(['name' => "Jazz Aviation LP"]);
Airline::where('internal_name', "jeju-air")->update(['name' => "Jeju Air"]);
Airline::where('internal_name', "jet2-com")->update(['name' => "Jet2.com"]);
Airline::where('internal_name', "jetblue")->update(['name' => "JetBlue"]);
Airline::where('internal_name', "jetgo")->update(['name' => "JetGo"]);
Airline::where('internal_name', "jetstar-airways-pty")->update(['name' => "Jetstar"]);
Airline::where('internal_name', "jetstar-japan")->update(['name' => "Jetstar Japan"]);
Airline::where('internal_name', "jiangxi-air-limited-dba-jiangxi-air")->update(['name' => "Jiangxi Air"]);
Airline::where('internal_name', "jin-air")->update(['name' => "Jin Air"]);
Airline::where('internal_name', "joint-stock-aviation-rusline")->update(['name' => "RusLine"]);
Airline::where('internal_name', "joint-stock-aurora-airlines")->update(['name' => "Aurora Airlines"]);
Airline::where('internal_name', "jordan-aviation")->update(['name' => "Jordan Aviation"]);
Airline::where('internal_name', "jsc-aircompany-scat")->update(['name' => "SCAT Airlines"]);
Airline::where('internal_name', "jsc-avion-express")->delete();
Airline::where('internal_name', "jsx")->update(['name' => "JSX"]);
Airline::where('internal_name', "juneyao-airlines")->update(['name' => "Juneyao Airlines"]);
Airline::where('internal_name', "kam-air")->update(['name' => "Kam Air"]);
Airline::where('internal_name', "kenmore-air")->update(['name' => "Kenmore Air"]);
Airline::where('internal_name', "kenya-airways")->update(['name' => "Kenya Airways"]);
Airline::where('internal_name', "klm")->update(['name' => "KLM"]);
Airline::where('internal_name', "klm-cityhopper")->update(['name' => "KLM Cityhopper"]);
Airline::where('internal_name', "k-mile-air")->update(['name' => "K-Mile Air"]);
Airline::where('internal_name', "korean-air")->update(['name' => "Korean Air"]);
Airline::where('internal_name', "kunming-airlines")->update(['name' => "Kunming Airlines"]);
Airline::where('internal_name', "kuwait-airways")->update(['name' => "Kuwait Airways"]);
Airline::where('internal_name', "lam")->update(['name' => "LAM Mozambique"]);
Airline::where('internal_name', "lan-airlines")->update(['name' => "Lan Airlines"]);
Airline::where('internal_name', "lan-colombia-airlines")->update(['name' => "Lan Colombia Airlines"]);
Airline::where('internal_name', "lanexang-airways")->update(['name' => "Lanexang Airways"]);
Airline::where('internal_name', "lao-airlines")->update(['name' => "Lao Airlines"]);
Airline::where('internal_name', "lao-skyway")->update(['name' => "Lao Skyway"]);
Airline::where('internal_name', "laser-airlines")->update(['name' => "LASER Airlines"]);
Airline::where('internal_name', "latam")->update(['name' => "LATAM"]);
Airline::where('internal_name', "latam-brasil")->update(['name' => "LATAM Brasil", 'logo' => 'JJ_2.png']);
Airline::where('internal_name', "latam-paraguay")->update(['name' => "LATAM Paraguay"]);
Airline::where('internal_name', "lauda-europe")->update(['name' => "Lauda Europe"]);
Airline::where('internal_name', "level")->update(['name' => "Level"]);
Airline::where('internal_name', "liat-air")->update(['name' => "LIAT Air"]);
Airline::where('internal_name', "libyan-airlines")->update(['name' => "Libyan Airlines"]);
Airline::where('internal_name', "libyan-wings")->update(['name' => "Libyan Wings"]);
Airline::where('internal_name', "linea-aerea-eco-jet-s-a")->update(['name' => "Linea Aerea Eco Jet S.A."]);
Airline::where('internal_name', "link-airways")->update(['name' => "Link Airways"]);
Airline::where('internal_name', "lion-airlines")->update(['name' => "Lion Airlines"]);
Airline::where('internal_name', "lj-air")->update(['name' => "LJ Air"]);
Airline::where('internal_name', "nord-wind")->update(['name' => "Nordwind Airlines"]);
Airline::where('internal_name', "loganair")->update(['name' => "Loganair"]);
Airline::where('internal_name', "lot-polish-airlines")->update(['name' => "LOT Polish Airlines"]);
Airline::where('internal_name', "lucky-air")->update(['name' => "Lucky Air"]);
Airline::where('internal_name', "lufthansa")->update(['name' => "Lufthansa"]);
Airline::where('internal_name', "lufthansa-cargo")->update(['name' => "Lufthansa Cargo"]);
Airline::where('internal_name', "lufthansa-city-airlines")->update(['name' => "Lufthansa City Airlines"]);
Airline::where('internal_name', "lufthansa-cityline")->update(['name' => "Lufthansa CityLine"]);
Airline::where('internal_name', "lufthansa-systems-ag")->delete();
Airline::where('internal_name', "lulutai-airlines")->update(['name' => "Lulutai Airlines"]);
Airline::where('internal_name', "luxair")->update(['name' => "Luxair"]);
Airline::where('internal_name', "mahan-air")->update(['name' => "Mahan Air"]);
Airline::where('internal_name', "malawian-airlines-3w")->update(['name' => "Malawian Airlines"]);
Airline::where('internal_name', "malaysia-airlines")->update(['name' => "Malaysia Airlines"]);
Airline::where('internal_name', "maldivian")->update(['name' => "Maldivian"]);
Airline::where('internal_name', "malindo-airways-sdn-bhd-malindo-a")->update(['name' => "Batik Air Malaysia"]);
Airline::where('internal_name', "malta-air")->update(['name' => "Malta Air"]);
Airline::where('internal_name', "mandarin-airlines")->update(['name' => "Mandarin Airlines"]);
Airline::where('internal_name', "mango-airlines-soc-trading-as-mango")->update(['name' => "Mango"]);
Airline::where('internal_name', "mann-yadanarpon-airlines")->update(['name' => "Mann Yadanarpon Airlines"]);
Airline::where('internal_name', "manta-air")->update(['name' => "Manta Air"]);
Airline::where('internal_name', "marabu")->update(['name' => "Marabu"]);
Airline::where('internal_name', "mas-air")->update(['name' => "MAS AIR"]);
Airline::where('internal_name', "mauritanian-airlines-international")->update(['name' => "Mauritania Airlines"]);
Airline::where('internal_name', "mavi-gok-airlines")->update(['name' => "Mavi Gok Airlines"]);
Airline::where('internal_name', "max-air")->update(['name' => "Max Air"]);
Airline::where('internal_name', "maya-island-air")->update(['name' => "Maya Island Air"]);
Airline::where('internal_name', "mea")->update(['name' => "Middle East Airlines"]);
Airline::where('internal_name', "medsky")->update(['name' => "Medsky"]);
Airline::where('internal_name', "mesa-airlines")->update(['name' => "Mesa Airlines"]);
Airline::where('internal_name', "mexicana-de-aviacion")->update(['name' => "Mexicana de Aviacion"]);
Airline::where('internal_name', "miat-mongolian-airlines")->update(['name' => "MIAT"]);
Airline::where('internal_name', "mingalar")->update(['name' => "Mingalar"]);
Airline::where('internal_name', "mistral-air")->update(['name' => "Mistral Air"]);
Airline::where('internal_name', "monacair")->update(['name' => "Monacair"]);
Airline::where('internal_name', "motor-sich-jsc")->update(['name' => "Motor-Sich"]);
Airline::where('internal_name', "myanmar-airways-international")->update(['name' => "Myanmar Airways International"]);
Airline::where('internal_name', "myanmar-national-airlines")->update(['name' => "Myanmar National Airlines"]);
Airline::where('internal_name', "myway-airlines")->update(['name' => "MyWay Airlines"]);
Airline::where('internal_name', "nam-air")->update(['name' => "Nam Air"]);
Airline::where('internal_name', "national-airlines")->update(['name' => "National Airlines"]);
Airline::where('internal_name', "national-air-dba-flynas")->update(['name' => "Flynas"]);
Airline::where('internal_name', "nauru-air-corporation-t-a-our-airline")->update(['name' => "Nauru Airlines"]);
Airline::where('internal_name', "neos")->update(['name' => "Neos"]);
Airline::where('internal_name', "nepal-airlines-corporation")->update(['name' => "Nepal Airlines"]);
Airline::where('internal_name', "nesma-airlines")->update(['name' => "Nesma Airlines"]);
Airline::where('internal_name', "nexus-airlines")->update(['name' => "Nexus Airlines"]);
Airline::where('internal_name', "ng-eagle")->update(['name' => "NG Eagle"]);
Airline::where('internal_name', "niger-airlines-s-a")->update(['name' => "Niger Airlines"]);
Airline::where('internal_name', "nile-air")->update(['name' => "Nile Air"]);
Airline::where('internal_name', "nine-air")->update(['name' => "Nine Air"]);
Airline::where('internal_name', "nippon-cargo-airlines-nca")->update(['name' => "Nippon Cargo Airlines"]);
Airline::where('internal_name', "nok-airlines-public-limited-dba-nok-air")->update(['name' => "Nok Air"]);
Airline::where('internal_name', "northwestern-air-lease")->update(['name' => "Northwestern Air"]);
Airline::where('internal_name', "north-wright-airways")->update(['name' => "North-Wright Airways"]);
Airline::where('internal_name', "norwegian-air-international")->update(['name' => "Norwegian Air International"]);
Airline::where('internal_name', "norwegian-air-shuttle-a-s")->update(['name' => "Norwegian Air Shuttle"]);
Airline::where('internal_name', "nouvelair")->update(['name' => "Nouvelair"]);
Airline::where('internal_name', "novoair")->update(['name' => "Novoair Limited"]);
Airline::where('internal_name', "ojsc-tajik-air")->update(['name' => "Tajik Air"]);
Airline::where('internal_name', "okay-airways")->update(['name' => "Okay Airways"]);
Airline::where('internal_name', "olympic-air")->update(['name' => "Olympic Air"]);
Airline::where('internal_name', "oman-air")->update(['name' => "Oman Air"]);
Airline::where('internal_name', "open-joint-stock-alrosa-mirny-air-enterprise")->delete();
Airline::where('internal_name', "oriental-air-bridge")->update(['name' => "Oriental Air Bridge"]);
Airline::where('internal_name', "overland-airways")->update(['name' => "Overland Airways"]);
Airline::where('internal_name', "pacific-airlines")->update(['name' => "Pacific Airlines"]);
Airline::where('internal_name', "pal-airlines")->update(['name' => "PAL Airlines"]);
Airline::where('internal_name', "paranair")->update(['name' => "Paranair"]);
Airline::where('internal_name', "passion-air")->update(['name' => "Passion Air"]);
Airline::where('internal_name', "pattaya-airways")->update(['name' => "Pattaya Airways"]);
Airline::where('internal_name', "peach-aviation")->update(['name' => "Peach Aviation Limited"]);
Airline::where('internal_name', "pegasus-airlines")->update(['name' => "Pegasus Airlines"]);
Airline::where('internal_name', "people-s")->update(['name' => "People's"]);
Airline::where('internal_name', "philippine-airlines")->update(['name' => "Philippine Airlines"]);
Airline::where('internal_name', "philippines-airasia")->update(['name' => "Philippines AirAsia"]);
Airline::where('internal_name', "pia")->update(['name' => "Pakistan International Airlines"]);
Airline::where('internal_name', "piedmont-airlines")->update(['name' => "Piedmont Airlines"]);
Airline::where('internal_name', "s-a")->update(['name' => "Plus Ultra"]);
Airline::where('internal_name', "pobeda")->update(['name' => "Pobeda"]);
Airline::where('internal_name', "polar-air-cargo-worldwide")->update(['name' => "Polar Air Cargo Worldwide"]);
Airline::where('internal_name', "polar-airlines-ojsc")->update(['name' => "Polar Airlines"]);
Airline::where('internal_name', "populair")->update(['name' => "Populair"]);
Airline::where('internal_name', "porter-airlines")->update(['name' => "Porter Airlines"]);
Airline::where('internal_name', "privilege-style-s-a")->update(['name' => "Privilege Style"]);
Airline::where('internal_name', "proflight-zambia")->update(['name' => "Proflight Zambia"]);
Airline::where('internal_name', "pt-batik-air-indonesia")->update(['name' => "Batik Air Indonesia"]);
Airline::where('internal_name', "pt-citilink-indonesia")->update(['name' => "Citilink Indonesia"]);
Airline::where('internal_name', "pt-sriwijaya-air")->update(['name' => "Sriwijaya Air"]);
Airline::where('internal_name', "pt-transnusa-aviation-mandiri")->update(['name' => "Transnusa"]);
Airline::where('internal_name', "pt-trigana-air")->update(['name' => "Trigana Air"]);
Airline::where('internal_name', "pt-wings-abadi-airlines")->update(['name' => "Wings Air"]);
Airline::where('internal_name', "qanot-sharq")->update(['name' => "Qanot Sharq"]);
Airline::where('internal_name', "qantas")->update(['name' => "Qantas"]);
Airline::where('internal_name', "qatar-airways")->update(['name' => "Qatar Airways"]);
Airline::where('internal_name', "qeshm-air")->update(['name' => "Qeshm Air"]);
Airline::where('internal_name', "qingdao-airlines")->update(['name' => "Qingdao Airlines"]);
Airline::where('internal_name', "rano-air")->update(['name' => "Rano Air"]);
Airline::where('internal_name', "red-sea-airlines")->update(['name' => "Red Sea Airlines"]);
Airline::where('internal_name', "airlines-400")->update(['name' => "Red Wings"]);
Airline::where('internal_name', "regional-air")->update(['name' => "Regional Air Services"]);
Airline::where('internal_name', "republic-airline")->update(['name' => "Republic Airline Inc.."]);
Airline::where('internal_name', "rex-regional-express")->update(['name' => "REX Regional Express"]);
Airline::where('internal_name', "rise-air")->update(['name' => "Rise Air"]);
Airline::where('internal_name', "riyadh-air")->update(['name' => "Riyadh Air"]);
Airline::where('internal_name', "rossiya-airlines")->update(['name' => "Rossiya Airlines"]);
Airline::where('internal_name', "rotana-jet-aviation-dba-rotana-jet")->update(['name' => "Rotana Jet"]);
Airline::where('internal_name', "royal-air-maroc")->update(['name' => "Royal Air Maroc"]);
Airline::where('internal_name', "royal-brunei")->update(['name' => "Royal Brunei"]);
Airline::where('internal_name', "royal-jordanian")->update(['name' => "Royal Jordanian"]);
Airline::where('internal_name', "ruili-airlines")->update(['name' => "Ruili Airlines"]);
Airline::where('internal_name', "rutaca-airlines")->update(['name' => "Rutaca Airlines"]);
Airline::where('internal_name', "rwandair")->update(['name' => "RwandAir"]);
Airline::where('internal_name', "ryanair")->update(['name' => "Ryanair"]);
Airline::where('internal_name', "ryanair-uk")->update(['name' => "Ryanair UK"]);
Airline::where('internal_name', "s7-airlines")->update(['name' => "S7 Airlines"]);
Airline::where('internal_name', "saa")->update(['name' => "South Africa Airways"]);
Airline::where('internal_name', "safair")->update(['name' => "Safair"]);
Airline::where('internal_name', "salamair")->update(['name' => "SalamAir"]);
Airline::where('internal_name', "samoa-airways")->update(['name' => "Samoa Airways"]);
Airline::where('internal_name', "sas")->update(['name' => "SAS"]);
Airline::where('internal_name', "sata-air-acores")->update(['name' => "SATA Air Açores"]);
Airline::where('internal_name', "sata-internacional")->update(['name' => "SATA Internacional"]);
Airline::where('internal_name', "satena")->update(['name' => "SATENA"]);
Airline::where('internal_name', "saudi-arabian-airlines")->update(['name' => "Saudia"]);
Airline::where('internal_name', "scoot-private")->update(['name' => "Scoot"]);
Airline::where('internal_name', "scott-air")->update(['name' => "Island Air Express"]);
Airline::where('internal_name', "seaborne-airlines")->update(['name' => "Seaborne Airlines"]);
Airline::where('internal_name', "sepehran-airlines")->update(['name' => "Sepehran Airlines"]);
Airline::where('internal_name', "serene-air")->update(['name' => "Serene Air"]);
Airline::where('internal_name', "servicios-aereos-nacionales-s-a-sansa")->update(['name' => "SANSA"]);
Airline::where('internal_name', "severstal-aircompany")->update(['name' => "Severstal Avia"]);
Airline::where('internal_name', "sf-airlines-limited")->update(['name' => "SF Airlines"]);
Airline::where('internal_name', "shandong-airlines")->update(['name' => "Shandong Airlines"]);
Airline::where('internal_name', "shanghai-airlines")->update(['name' => "Shanghai Airlines"]);
Airline::where('internal_name', "sharp-airlines")->update(['name' => "Sharp Airlines"]);
Airline::where('internal_name', "shenzhen-airlines")->update(['name' => "Shenzhen Airlines"]);
Airline::where('internal_name', "shirak-avia")->update(['name' => "Shirak Avia"]);
Airline::where('internal_name', "shree-airlines")->update(['name' => "Shree Airlines"]);
Airline::where('internal_name', "sia-cargo")->update(['name' => "SIA Cargo"]);
Airline::where('internal_name', "sichuan-airlines")->update(['name' => "Sichuan Airlines"]);
Airline::where('internal_name', "silk-way-west-airlines")->update(['name' => "Silk Way West Airlines"]);
Airline::where('internal_name', "singapore-airlines")->update(['name' => "Singapore Airlines"]);
Airline::where('internal_name', "skippers-aviation")->update(['name' => "Skippers Aviation"]);
Airline::where('internal_name', "sky-airline-peru")->update(['name' => "Sky Airline Peru"]);
Airline::where('internal_name', "skyalps")->update(['name' => "SkyAlps"]);
Airline::where('internal_name', "sky-angkor-airlines")->update(['name' => "Sky Angkor Airlines"]);
Airline::where('internal_name', "sky-express-s-a")->update(['name' => "Sky Express"]);
Airline::where('internal_name', "skyfru")->update(['name' => "SkyFru"]);
Airline::where('internal_name', "skymark-airlines")->update(['name' => "Skymark Airlines"]);
Airline::where('internal_name', "sky-taxi-sp-z-o-o")->update(['name' => "SkyTaxi"]);
Airline::where('internal_name', "skyup-airlines")->update(['name' => "SkyUp Airlines"]);
Airline::where('internal_name', "skyup-mt")->update(['name' => "SkyUp MT"]);
Airline::where('internal_name', "skyward-airlines")->update(['name' => "Skyward Airlines"]);
Airline::where('internal_name', "skywest")->update(['name' => "Skywest"]);
Airline::where('internal_name', "skywest-airlines")->update(['name' => "SkyWest Airlines"]);
Airline::where('internal_name', "smartavia")->update(['name' => "Smartavia"]);
Airline::where('internal_name', "smartwings")->update(['name' => "SmartWings"]);
Airline::where('internal_name', "smartwings-hungary")->update(['name' => "Smartwings Hungary"]);
Airline::where('internal_name', "smartwings-poland")->update(['name' => "Smartwings Poland"]);
Airline::where('internal_name', "smartwings-slovakia")->update(['name' => "Smartwings Slovakia"]);
Airline::where('internal_name', "solaseed-air")->update(['name' => "Solaseed Air"]);
Airline::where('internal_name', "solomon-airlines")->update(['name' => "Solomon Airlines"]);
Airline::where('internal_name', "aircompany-somon-air")->update(['name' => "Somon Air"]);
Airline::where('internal_name', "sounds-air-travel-tourism")->update(['name' => "Sounds Air"]);
Airline::where('internal_name', "south-east-asian-airlines-seair-international")->update(['name' => "SEAIR"]);
Airline::where('internal_name', "southern-air-charter")->update(['name' => "Southern Air Charter"]);
Airline::where('internal_name', "southern-airways-express")->update(['name' => "Southern Airways Express"]);
Airline::where('internal_name', "southern-sky-airlines")->update(['name' => "Southern Sky Airlines"]);
Airline::where('internal_name', "southwest-airlines")->update(['name' => "Southwest Airlines"]);
Airline::where('internal_name', "southwind-airlines")->update(['name' => "Southwind Airlines"]);
Airline::where('internal_name', "spicejet")->update(['name' => "SpiceJet"]);
Airline::where('internal_name', "spirit")->delete();
Airline::where('internal_name', "spirit-airlines")->update(['name' => "Spirit"]);
Airline::where('internal_name', "spring-airlines-japan")->update(['name' => "Spring Airlines"]);
Airline::where('internal_name', "spring-japan")->delete();
Airline::where('internal_name', "sprintair-sa")->update(['name' => "Sprintair"]);
Airline::where('internal_name', "srilankan-airlines")->update(['name' => "SriLankan"]);
Airline::where('internal_name', "star-flyer")->update(['name' => "Star Flyer"]);
Airline::where('internal_name', "starlux-airlines")->update(['name' => "Starlux"]);
Airline::where('internal_name', "star-up")->update(['name' => "Star Perú"]);
Airline::where('internal_name', "st-barth-commuter")->update(['name' => "St Barth Commuter"]);
Airline::where('internal_name', "stp-airways")->update(['name' => "STP Airways"]);
Airline::where('internal_name', "sudan-airways")->update(['name' => "Sudan Airways"]);
Airline::where('internal_name', "sun-air-of-scandinavia-a-s")->update(['name' => "Sun-Air"]);
Airline::where('internal_name', "sunclass-airlines")->update(['name' => "Sunclass Airlines"]);
Airline::where('internal_name', "sun-country-airlines")->update(['name' => "Sun Country Airlines"]);
Airline::where('internal_name', "sunexpress")->update(['name' => "SunExpress"]);
Airline::where('internal_name', "sunlight-air")->update(['name' => "Sunlight Air"]);
Airline::where('internal_name', "sun-phuquoc")->update(['name' => "Sun PhuQuoc"]);
Airline::where('internal_name', "sunrise-airways")->update(['name' => "Sunrise Airways"]);
Airline::where('internal_name', "sunrise-airways-s-a")->delete();
Airline::where('internal_name', "sunrise-dominicana")->update(['name' => "Sunrise Dominicana"]);
Airline::where('internal_name', "suparna-airlines")->update(['name' => "Suparna Airlines"]);
Airline::where('internal_name', "super-air-jet")->update(['name' => "Super Air Jet"]);
Airline::where('internal_name', "surinam-airways")->update(['name' => "Surinam Airways"]);
Airline::where('internal_name', "swiss")->update(['name' => "SWISS"]);
Airline::where('internal_name', "sylt-air-gmbh")->update(['name' => "Sylt Air"]);
Airline::where('internal_name', "syrianair")->update(['name' => "Syrianair"]);
Airline::where('internal_name', "taag-angola-airlines")->update(['name' => "TAAG Angola Airlines"]);
Airline::where('internal_name', "tacv-cabo-verde-airlines")->update(['name' => "TACV Cabo Verde Airlines"]);
Airline::where('internal_name', "tailwind-hava-yollari-a-s")->update(['name' => "Tailwind Airlines"]);
Airline::where('internal_name', "tam-linhas-aereas")->update(['name' => "TAM Linhas Aereas"]);
Airline::where('internal_name', "tap-express")->update(['name' => "TAP Express"]);
Airline::where('internal_name', "tap-portugal")->update(['name' => "TAP Portugal"]);
Airline::where('internal_name', "tar-aerolineas")->update(['name' => "TAR Aerolineas"]);
Airline::where('internal_name', "tarco-air")->update(['name' => "Tarco Air"]);
Airline::where('internal_name', "tarom")->update(['name' => "TAROM"]);
Airline::where('internal_name', "tassili-airlines")->delete();
Airline::where('internal_name', "tezjet")->update(['name' => "TezJet"]);
Airline::where('internal_name', "thai-airasia")->update(['name' => "Thai AirAsia"]);
Airline::where('internal_name', "thai-airasia-x-limited")->update(['name' => "Thai Airasia X"]);
Airline::where('internal_name', "thai-airways-international")->update(['name' => "Thai Airways International"]);
Airline::where('internal_name', "thai-lion-air")->update(['name' => "Thai Lion Air"]);
Airline::where('internal_name', "thai-lion-mentari")->delete();
Airline::where('internal_name', "tianjin-airlines")->update(['name' => "Tianjin Airlines"]);
Airline::where('internal_name', "tibet-airlines-corporation")->update(['name' => "Tibet Airlines"]);
Airline::where('internal_name', "tigerair-taiwan")->update(['name' => "Tigerair Taiwan"]);
Airline::where('internal_name', "titan-airways")->update(['name' => "Titan Airways"]);
Airline::where('internal_name', "tnt-airways-s-a")->update(['name' => "TNT Airways"]);
Airline::where('internal_name', "toki-air")->update(['name' => "Toki Air"]);
Airline::where('internal_name', "trade-air")->update(['name' => "Trade Air"]);
Airline::where('internal_name', "tradewind-aviation")->update(['name' => "Tradewind Aviation"]);
Airline::where('internal_name', "transavia-france")->update(['name' => "Transavia France"]);
Airline::where('internal_name', "transportes-aereos-guatemaltecos-s")->update(['name' => "Transportes Aereos Guatemaltecos"]);
Airline::where('internal_name', "tropic-air")->update(['name' => "Tropic Air Limited"]);
Airline::where('internal_name', "tsaradia")->update(['name' => "Tsaradia"]);
Airline::where('internal_name', "tui-airlines-belgium-t-a-jetairfly")->update(['name' => "TUI fly Belgium"]);
Airline::where('internal_name', "arkefly")->update(['name' => "TUI fly Netherlands"]);
Airline::where('internal_name', "tui-airways")->update(['name' => "TUI Airways"]);
Airline::where('internal_name', "tuifly")->update(['name' => "TUI fly Germany"]);
Airline::where('internal_name', "tuifly-nordic-ab")->update(['name' => "TUI fly Nordic"]);
Airline::where('internal_name', "tunisair")->update(['name' => "Tunisair"]);
Airline::where('internal_name', "tunisair-express")->update(['name' => "Tunisair Express"]);
Airline::where('internal_name', "thy-turkish-airlines")->update(['name' => "Turkish Airlines"]);
Airline::where('internal_name', "turkmenistan-airlines")->update(['name' => "Turkmenistan Airlines"]);
Airline::where('internal_name', "turpial")->update(['name' => "Turpial Airlines"]);
Airline::where('internal_name', "tus-airways")->update(['name' => "TUS Airways"]);
Airline::where('internal_name', "t-way-air")->update(['name' => "T'way Air"]);
Airline::where('internal_name', "twin-jet")->update(['name' => "Twin Jet"]);
Airline::where('internal_name', "uganda-airlines")->update(['name' => "Uganda Airlines"]);
Airline::where('internal_name', "ukraine-international-airlines")->update(['name' => "Ukraine International Airlines"]);
Airline::where('internal_name', "uls-airlines-cargo")->update(['name' => "ULS Airlines Cargo"]);
Airline::where('internal_name', "umza-air")->update(['name' => "Umza Air"]);
Airline::where('internal_name', "uni-air")->update(['name' => "Uni Air"]);
Airline::where('internal_name', "united-airlines")->update(['name' => "United Airlines"]);
Airline::where('internal_name', "uniworld-air-cargo-corp")->update(['name' => "Uniworld"]);
Airline::where('internal_name', "ups-airlines")->update(['name' => "UPS Airlines"]);
Airline::where('internal_name', "ural-airlines")->update(['name' => "Ural Airlines"]);
Airline::where('internal_name', "urumqi-airlines")->update(['name' => "Urumqi Air"]);
Airline::where('internal_name', "us-airways")->update(['name' => "US Airways"]);
Airline::where('internal_name', "us-bangla-airlines")->update(['name' => "US-Bangla Airlines"]);
Airline::where('internal_name', "utair")->update(['name' => "UTair"]);
Airline::where('internal_name', "uvt-aero")->update(['name' => "UVT Aero"]);
Airline::where('internal_name', "uzbekistan-airways")->update(['name' => "Uzbekistan Airways"]);
Airline::where('internal_name', "valuejet")->update(['name' => "Valuejet"]);
Airline::where('internal_name', "vasco")->update(['name' => "VASCO"]);
Airline::where('internal_name', "v-australia")->update(['name' => "V Australia"]);
Airline::where('internal_name', "venezolana")->update(['name' => "Venezolana"]);
Airline::where('internal_name', "vieques-air-link")->update(['name' => "Vieques Air Link"]);
Airline::where('internal_name', "vietjet-air-qazaqstan")->update(['name' => "Vietjet Air Qazaqstan"]);
Airline::where('internal_name', "vietjet-aviation-joint-stock")->update(['name' => "Vietjet"]);
Airline::where('internal_name', "vietnam-airlines")->update(['name' => "Vietnam Airlines"]);
Airline::where('internal_name', "vietravel-airlines")->update(['name' => "Vietravel Airlines"]);
Airline::where('internal_name', "flyme")->update(['name' => "Villa Air"]);
Airline::where('internal_name', "virgin-america")->update(['name' => "Virgin America"]);
Airline::where('internal_name', "virgin-atlantic")->update(['name' => "Virgin Atlantic"]);
Airline::where('internal_name', "virgin-australia")->update(['name' => "Virgin Australia"]);
Airline::where('internal_name', "virgin-australia-regional")->update(['name' => "Virgin Australia Regional"]);
Airline::where('internal_name', "virgin-blue-airlines")->update(['name' => "Virgin Blue Airlines"]);
Airline::where('internal_name', "aeroenlaces-nacionales-s-a-de-c-v")->update(['name' => "Viva"]);
Airline::where('internal_name', "volaris")->update(['name' => "Volaris"]);
Airline::where('internal_name', "volaris-costa-rica")->update(['name' => "Volaris Costa Rica"]);
Airline::where('internal_name', "volaris-el-salvador")->update(['name' => "Volaris El Salvador"]);
Airline::where('internal_name', "volotea")->update(['name' => "Volotea"]);
Airline::where('internal_name', "vueling")->update(['name' => "Vueling"]);
Airline::where('internal_name', "wamos-air")->update(['name' => "Wamos Air"]);
Airline::where('internal_name', "wasaya-airways")->update(['name' => "Wasaya Airways"]);
Airline::where('internal_name', "western-air")->update(['name' => "Western Air"]);
Airline::where('internal_name', "westjet")->update(['name' => "WestJet"]);
Airline::where('internal_name', "westjet-encore")->update(['name' => "WestJet Encore"]);
Airline::where('internal_name', "wideroe")->update(['name' => "Wideroe"]);
Airline::where('internal_name', "wind-rose-aviation")->update(['name' => "Wind Rose Aviation Company"]);
Airline::where('internal_name', "wingo")->update(['name' => "Wingo"]);
Airline::where('internal_name', "wingo-panama")->update(['name' => "Wingo Panama"]);
Airline::where('internal_name', "wizz-air")->update(['name' => "Wizz Air Hungary"]);
Airline::where('internal_name', "wizz-air-malta")->update(['name' => "Wizz Air Malta"]);
Airline::where('internal_name', "wizz-air-uk")->update(['name' => "Wizz Air UK"]);
Airline::where('internal_name', "world2fly")->update(['name' => "World2Fly"]);
Airline::where('internal_name', "world2fly-portugal")->update(['name' => "World2Fly Portugal"]);
Airline::where('internal_name', "xiamen-airlines")->update(['name' => "Xiamen Airlines"]);
Airline::where('internal_name', "yakutia-airlines")->update(['name' => "Yakutia Airlines"]);
Airline::where('internal_name', "yamal-airlines")->update(['name' => "Yamal Airlines"]);
Airline::where('internal_name', "yanair")->update(['name' => "Yan Air"]);
Airline::where('internal_name', "yemenia")->update(['name' => "Yemenia"]);
Airline::where('internal_name', "yeti-airlines")->update(['name' => "Yeti Airlines"]);
Airline::where('internal_name', "yto-cargo-airlines")->update(['name' => "YTO Cargo"]);
Airline::where('internal_name', "zambia-airways")->update(['name' => "Zambia Airways"]);
Airline::where('internal_name', "zhejiang-loong-airlines")->update(['name' => "Loong Air"]);
Airline::where('internal_name', "zimex-aviation")->delete();
Airline::where('internal_name', "zipair")->update(['name' => "ZIPAIR"]);
Airline::all()->each(function ($airline) {
$internalName = Str::slug($airline->name);
$airline->update(['internal_name' => $internalName]);
});
Schema::table('airlines', function (Blueprint $table) {
$table->unique('internal_name');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
@@ -0,0 +1,92 @@
<?php
use App\Models\Airline;
use App\Models\Country;
use App\Models\SeatType;
use App\Models\UserFlight;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function createAirline(
string $name,
bool $active,
string $countryCode,
?string $iataCode = null,
?string $icaoCode = null,
?string $logo = null,
string $internalName = null,
): self {
$country = Country::where('code', $countryCode)->firstOrFail();
$logo = $logo ?? $iataCode . '.png';
Airline::create([
'IATA_code' => $iataCode,
'ICAO_code' => $icaoCode,
'name' => $name,
'internal_name' => $internalName,
'active' => $active,
'logo' => $logo,
'country_id' => $country->id,
]);
return $this;
}
function createAirlines(): void{
$this
->createAirline(name: 'Horizontal Falls Seaplane Adventures', active: true, countryCode: 'AU', logo: 'horizontal-falls-seaplane-adventures.png', internalName: 'horizontal-falls-seaplane-adventures')
->createAirline(name: 'Pineapple Air', active: true, countryCode: 'BS', icaoCode: 'PNP', logo: 'pineapple-air.png', internalName: 'pineapple-air')
->createAirline(name: 'ATA Airlines', active: true, countryCode: 'IR', iataCode: 'I3', icaoCode: 'TBZ', logo: 'ata-airlines.png', internalName: 'ata-airlines')
->createAirline(name: 'Chabahar Air', active: true, countryCode: 'IR', iataCode: null, icaoCode: 'IRU', logo: 'chabahar-airlines.png', internalName: 'chabahar-airlines')
->createAirline(name: 'Kish Air', active: true, countryCode: 'IR', iataCode: 'Y9', icaoCode: 'KIS', logo: 'kish-air.png', internalName: 'kish-air')
->createAirline(name: 'Meraj Airlines', active: true, countryCode: 'IR', iataCode: 'JI', icaoCode: 'MRJ', logo: 'meraj-airlines.png', internalName: 'meraj-airlines')
->createAirline(name: 'Qazaq Air', active: false, countryCode: 'KZ', iataCode: 'IQ', icaoCode: 'QAZ', logo: 'qazaq-air.png', internalName: 'qazaq-air')
->createAirline(name: 'Raimon Airways', active: true, countryCode: 'IR', iataCode: null, icaoCode: 'RAI', logo: 'raimon-airways.png', internalName: 'raimon-airways')
->createAirline(name: 'Saha Airlines', active: true, countryCode: 'IR', iataCode: null, icaoCode: 'IRZ', logo: 'saha-airlines.png', internalName: 'saha-airlines')
->createAirline(name: 'Yazd Airways', active: true, countryCode: 'IR', iataCode: null, icaoCode: 'DZD', logo: 'yazd-airways.png', internalName: 'yazd-airways')
->createAirline(name: 'Zagros Airlines', active: true, countryCode: 'IR', iataCode: 'ZO', icaoCode: 'IZG', logo: 'zagros-airlines.png', internalName: 'zagros-airlines')
->createAirline(name: 'Taban Airlines', active: true, countryCode: 'IR', iataCode: null, icaoCode: 'TBN', logo: 'taban-airlines.png', internalName: 'taban-airlines')
->createAirline(name: 'Maun Helicopter Horizons', active: true, countryCode: 'BW', iataCode: null, icaoCode: null, logo: 'blank.png', internalName: 'maun-helicopter-horizons')
->createAirline(name: 'Pacific Mission Aviation', active: true, countryCode: 'PW', iataCode: null, icaoCode: null, logo: 'pacific-mission-aviation.png', internalName: 'pacific-mission-aviation')
->createAirline(name: 'Jetstar Pacific', active: false, countryCode: 'VN', iataCode: 'BL', icaoCode: 'PIC', logo: 'jq.png', internalName: 'jetstar-pacific')
->createAirline(name: 'Jetsmart', active: true, countryCode: 'CL', iataCode: 'JA', icaoCode: 'JAT', logo: 'ja.png', internalName: 'jetsmart')
->createAirline(name: 'Jetsmart Peru', active: true, countryCode: 'PE', iataCode: 'JZ', icaoCode: 'JAP', logo: 'jz.png', internalName: 'jetsmart-peru')
->createAirline(name: 'Jetsmart Argentina', active: true, countryCode: 'AR', iataCode: 'WJ', icaoCode: 'JES', logo: 'wj.png', internalName: 'jetsmart-argentina')
->createAirline(name: 'Jetsmart Colombia', active: true, countryCode: 'CO', iataCode: 'J6', icaoCode: 'JEC', logo: 'j6.png', internalName: 'jetsmart-colombia')
;
}
public function up(): void
{
DB::table('airlines')->whereNull('logo')->update(['logo' => 'blank.png']);
Schema::table('airlines', function (Blueprint $table) {
$table->string('logo')->default('blank.png')->nullable(false)->change();
});
Airline::where('name', 'AVIANCA')->update(['name' => 'Avianca']);
$this->createAirlines();
UserFlight::where('seat_type_id', null)->update(['seat_type_id' => 0]);
UserFlight::where('flight_reason_id', null)->update(['flight_reason_id' => 0]);
UserFlight::where('flight_class_id', null)->update(['flight_class_id' => 0]);
UserFlight::where('flight_reason_id', 0)->update(['flight_reason_id' => 1]);
SeatType::where('id', 0)->update(['name' => 'Unassigned']);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
@@ -0,0 +1,36 @@
<?php
use App\Models\Airport;
use App\Models\Country;
use App\Models\Region;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Airport::create([
'name' => 'Horizontal Falls Pontoon',
'region_id' => Region::whereCode('AU-WA')->first()->id,
'municipality' => 'Horizontal Falls',
'latitude_deg' => -16.373295,
'longitude_deg' => 123.964757,
'elevation_ft' => 0,
'type' => 'seaplane_base',
'timezone' => 'Australia/Perth',
]);
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
@@ -0,0 +1,36 @@
<?php
use App\Models\Airline;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$airlines = [
['internalName' => 'jetstar-pacific', 'logo' => 'JQ.png'],
['internalName' => 'jetsmart', 'logo' => 'JA.png'],
['internalName' => 'jetsmart-peru', 'logo' => 'JZ.png'],
['internalName' => 'jetsmart-argentina', 'logo' => 'WJ.png'],
['internalName' => 'jetsmart-colombia', 'logo' => 'J6.png'],
];
foreach ($airlines as $airline) {
Airline::where('internal_name', $airline['internalName'])
->update(['logo' => $airline['logo']]);
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
@@ -0,0 +1,142 @@
<?php
use App\Models\FlightClass;
use App\Models\FlightReason;
use App\Models\UserFlight;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
// ---------------------------------------------------------------------
// Crew Types
// ---------------------------------------------------------------------
Schema::create('crew_types', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('internal_name')->unique();
});
DB::table('crew_types')->insert([
['name' => 'Unspecified', 'internal_name' => 'unspecified'],
['name' => 'Cabin Crew', 'internal_name' => 'cabin_crew'],
['name' => 'Purser / CSM', 'internal_name' => 'purser'],
['name' => 'Captain', 'internal_name' => 'captain'],
['name' => 'First Officer', 'internal_name' => 'first_officer'],
['name' => 'Second Officer', 'internal_name' => 'second_officer'],
['name' => 'Deadhead', 'internal_name' => 'deadhead'],
['name' => 'Marshal / Security', 'internal_name' => 'marshal'],
]);
// ---------------------------------------------------------------------
// Followees
// ---------------------------------------------------------------------
Schema::create('followees', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
$table->foreignId('followee_id')->constrained('users')->cascadeOnDelete();
$table->timestamps();
$table->unique(['user_id', 'followee_id']);
});
// ---------------------------------------------------------------------
// User Actions
// ---------------------------------------------------------------------
Schema::create('user_actions', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
$table->unsignedBigInteger('user_flight_id');
$table->text('message');
$table->timestamps();
});
// ---------------------------------------------------------------------
// Achievements
// ---------------------------------------------------------------------
Schema::create('achievements', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('internal_name')->unique();
$table->text('description');
$table->string('icon');
});
// ---------------------------------------------------------------------
// User Achievements
// ---------------------------------------------------------------------
Schema::create('user_achievements', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained('users')->cascadeOnDelete();
$table->foreignId('achievement_id')->constrained('achievements')->cascadeOnDelete();
$table->timestamps();
$table->unique(['user_id', 'achievement_id']);
});
DB::statement('ALTER TABLE flight_classes ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY');
DB::statement('ALTER TABLE flight_reasons ALTER COLUMN id ADD GENERATED BY DEFAULT AS IDENTITY');
DB::statement("
SELECT setval(
pg_get_serial_sequence('flight_classes', 'id'),
(SELECT MAX(id) FROM flight_classes)
)
");
DB::statement("
SELECT setval(
pg_get_serial_sequence('flight_reasons', 'id'),
(SELECT MAX(id) FROM flight_reasons)
)
");
DB::table('flight_classes')->insert([
['name' => 'General Aviation'],
['name' => 'Crew'],
]);
DB::table('flight_reasons')->insert([
['name' => 'Visiting Friends / Relatives'],
]);
Schema::table('flight_classes', function (Blueprint $table) {
$table->string('internal_name')->nullable();
});
DB::table('flight_classes')->get()->each(function ($row) {
DB::table('flight_classes')
->where('id', $row->id)
->update(['internal_name' => Str::slug($row->name, '_')]);
});
Schema::table('flight_classes', function (Blueprint $table) {
$table->string('internal_name')->nullable(false)->unique()->change();
});
Schema::table('user_flights', function (Blueprint $table) {
$table->foreignId('crew_type_id')->nullable()->constrained('crew_types')->nullOnDelete();
});
$economy = FlightClass::where('internal_name', 'economy')->first();
$unspecified = FlightClass::where('internal_name', 'unspecified')->first();
UserFlight::where('flight_class_id', $unspecified->id)->update(['flight_class_id' => $economy->id]);
FlightReason::where('name', 'Other')->update(['id' => 999]);
}
public function down(): void
{
Schema::dropIfExists('user_achievements');
Schema::dropIfExists('achievements');
Schema::dropIfExists('user_actions');
Schema::dropIfExists('followees');
Schema::dropIfExists('crew_types');
DB::table('flight_classes')->whereIn('name', ['General Aviation', 'Crew'])->delete();
DB::table('flight_reasons')->where('name', 'Crew')->delete();
}
};
@@ -0,0 +1,65 @@
<?php
use App\Models\Airline;
use App\Models\Country;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function createAirline(
string $name,
bool $active,
string $countryCode,
?string $iataCode = null,
?string $icaoCode = null,
?string $logo = null,
?string $internalName = null,
): self {
$country = Country::where('code', $countryCode)->firstOrFail();
$internalName = $internalName ?? Str::slug($name);
$logo = $logo ?? $iataCode . '.png';
Airline::create([
'IATA_code' => $iataCode,
'ICAO_code' => $icaoCode,
'name' => $name,
'internal_name' => $internalName,
'active' => $active,
'logo' => $logo,
'country_id' => $country->id,
]);
return $this;
}
/**
* Run the migrations.
*/
public function up(): void
{
$this
->createAirline(name: 'Fly540', active: false, countryCode: 'KE', iataCode: '5H', icaoCode: 'FFV', logo: 'fly540.png')
->createAirline(name: 'Ansett Australia', active: false, countryCode: 'AU', iataCode: 'AN', icaoCode: 'AAA', logo: 'ansett.png')
->createAirline(name: 'Ansett New Zealand', active: false, countryCode: 'AU', iataCode: 'ZQ', icaoCode: 'NZA', logo: 'ansett.png')
->createAirline(name: 'Flight West', active: false, countryCode: 'AU', iataCode: 'YC', icaoCode: 'FWQ', logo: 'flight-west.png')
->createAirline(name: 'Antarctic Airways', active: true, countryCode: 'CL', iataCode: 'V5', icaoCode: 'DAP', logo: 'antarctic-airways.png')
->createAirline(name: 'Amaszonas Uruguay', active: false, countryCode: 'UY', iataCode: 'Z7', icaoCode: 'AUZ', logo: 'amaszonas-uruguay.png')
->createAirline(name: 'Amaszonas', active: false, countryCode: 'BO', iataCode: 'Z8', icaoCode: 'AZN', logo: 'amaszonas.png')
->createAirline(name: 'Czech Airlines', active: false, countryCode: 'CZ', iataCode: 'OK', icaoCode: 'CSA', logo: 'csa-czech-airlines.png')
;
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
@@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
//
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
@@ -0,0 +1,29 @@
<?php
use App\Models\Airport;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('user_actions', function (Blueprint $table) {
$table->dropColumn('message');
$table->string('type')->after('user_flight_id');
$table->dropColumn('user_flight_id');
$table->json('data')->after('type');
});
Airport::whereMunicipality('Fayetteville/Springdale/Rogers')->update(['municipality' => 'Fayetteville']);
}
public function down(): void
{
Schema::table('user_actions', function (Blueprint $table) {
$table->dropColumn(['type', 'data']);
$table->text('message')->after('user_flight_id');
});
}
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->text('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamp('expires_at')->nullable()->index();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('personal_access_tokens');
}
};
+3
View File
@@ -20,6 +20,9 @@ http {
fastcgi_param HTTPS on;
fastcgi_param HTTP_X_FORWARDED_PROTO https;
include fastcgi_params;
fastcgi_buffers 32 32k;
fastcgi_buffer_size 64k;
}
}
}
-10
View File
@@ -1,10 +0,0 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["resources/js/*"],
"ziggy-js": ["./vendor/tightenco/ziggy"]
}
},
"exclude": ["node_modules", "public"]
}
+505 -65
View File
File diff suppressed because it is too large Load Diff
+15
View File
@@ -11,6 +11,8 @@
"@inertiajs/vue3": "^2.0.0",
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/vite": "^4.0.0",
"@types/leaflet": "^1.9.21",
"@types/node": "^25.5.0",
"@vitejs/plugin-vue": "^6.0.0",
"autoprefixer": "^10.4.12",
"axios": "^1.11.0",
@@ -19,7 +21,20 @@
"laravel-vite-plugin": "^3.0.0",
"postcss": "^8.4.31",
"tailwindcss": "^3.2.1",
"typescript": "^6.0.2",
"vite": "^8.0.0",
"vite-plugin-vuetify": "^2.1.3",
"vue": "^3.4.0"
},
"dependencies": {
"@mdi/font": "^7.4.47",
"apexcharts": "^5.10.5",
"chart.js": "^4.5.1",
"echarts": "^6.0.0",
"flag-icons": "^7.5.0",
"maplibre-gl": "^5.22.0",
"vue-echarts": "^8.0.1",
"vue3-apexcharts": "^1.11.1",
"vuetify": "^4.0.5"
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More