Files
ladill-link/app/Console/Commands/UpdateGeoIpDatabaseCommand.php
T
isaaccladandCursor 5e87debe32
Deploy Ladill Link / deploy (push) Successful in 41s
Clarify GeoIP update env setup for cached config deployments.
Point operators at shared/.env and config:clear when MaxMind credentials are missing.

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

100 lines
3.4 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 = trim((string) config('link.maxmind_account_id', ''));
$licenseKey = trim((string) config('link.maxmind_license_key', ''));
if ($accountId === '' || $licenseKey === '') {
$envPath = realpath(base_path('.env')) ?: base_path('.env');
$configCached = is_file(base_path('bootstrap/cache/config.php'));
$this->error('Set MAXMIND_ACCOUNT_ID and MAXMIND_LICENSE_KEY before updating GeoIP data.');
$this->line('');
$this->line('Production uses the shared env file (current/.env is usually a symlink):');
$this->line(' '.$envPath);
$this->line('');
$this->line('Add both variables there, then refresh config:');
$this->line(' php artisan config:clear');
$this->line(' php artisan link:geoip-update');
$this->line(' php artisan config:cache');
if ($configCached) {
$this->warn('Config is cached — Laravel will ignore new .env values until you run config:clear.');
}
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);
}
}
}