Files
ladill-link/app/Console/Commands/UpdateGeoIpDatabaseCommand.php
T
isaaccladandCursor 344bf76391
Deploy Ladill Link / deploy (push) Successful in 39s
Add GeoIP country fallback for link click analytics.
Resolve countries from CDN headers first, then MaxMind GeoLite2 via visitor IP, with an artisan command to download and refresh the database.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 23:36:01 +00:00

85 lines
2.6 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Http;
use Symfony\Component\Finder\Finder;
class UpdateGeoIpDatabaseCommand extends Command
{
protected $signature = 'link:geoip-update';
protected $description = 'Download the MaxMind GeoLite2 Country database for link click geolocation';
public function handle(): int
{
$accountId = (string) config('link.maxmind_account_id', '');
$licenseKey = (string) config('link.maxmind_license_key', '');
if ($accountId === '' || $licenseKey === '') {
$this->error('Set MAXMIND_ACCOUNT_ID and MAXMIND_LICENSE_KEY in .env before updating GeoIP data.');
return self::FAILURE;
}
$targetDir = dirname((string) config('link.geoip_database'));
File::ensureDirectoryExists($targetDir);
$this->info('Downloading GeoLite2-Country database from MaxMind…');
$response = Http::withBasicAuth($accountId, $licenseKey)
->timeout(180)
->withOptions(['allow_redirects' => true])
->get('https://download.maxmind.com/geoip/databases/GeoLite2-Country/download', [
'suffix' => 'tar.gz',
]);
if ($response->failed()) {
$this->error('MaxMind download failed: HTTP '.$response->status());
return self::FAILURE;
}
$archivePath = $targetDir.'/GeoLite2-Country.tar.gz';
$extractDir = $targetDir.'/extract-'.uniqid('', true);
file_put_contents($archivePath, $response->body());
try {
File::ensureDirectoryExists($extractDir);
$process = new \Symfony\Component\Process\Process([
'tar', '-xzf', $archivePath, '-C', $extractDir,
]);
$process->mustRun();
$finder = Finder::create()
->files()
->name('GeoLite2-Country.mmdb')
->in($extractDir);
$database = null;
foreach ($finder as $file) {
$database = $file->getPathname();
break;
}
if ($database === null) {
$this->error('GeoLite2-Country.mmdb was not found in the downloaded archive.');
return self::FAILURE;
}
$target = (string) config('link.geoip_database');
File::copy($database, $target);
$this->info('GeoIP database updated at '.$target);
return self::SUCCESS;
} finally {
@unlink($archivePath);
File::deleteDirectory($extractDir);
}
}
}