mirror of
https://github.com/Respect/Validation.git
synced 2026-03-15 06:45:44 +01:00
It makes more sense to use PHP to generate PHP code than to use Bash. I love writing Bash scripts, but I know it's not for everyone, and they can become quite complex. Porting them to PHP code also lowers the barrier for people to change them. While I was making those changes, I also noticed a problem with how we save the domain suffixes. We're converting all of them to ASCII, so we are not preserving languages such as Chinese, Thai, and Hebrew, which use non-ASCII characters.
130 lines
3.8 KiB
PHP
130 lines
3.8 KiB
PHP
<?php
|
|
|
|
/*
|
|
* Copyright (c) Alexandre Gomes Gaigalas <alganet@gmail.com>
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Respect\Dev\Commands;
|
|
|
|
use Symfony\Component\Console\Attribute\AsCommand;
|
|
use Symfony\Component\Console\Command\Command;
|
|
use Symfony\Component\Console\Input\InputInterface;
|
|
use Symfony\Component\Console\Output\OutputInterface;
|
|
use Symfony\Component\Console\Style\SymfonyStyle;
|
|
use Symfony\Component\VarExporter\VarExporter;
|
|
|
|
use function basename;
|
|
use function count;
|
|
use function dirname;
|
|
use function explode;
|
|
use function file_get_contents;
|
|
use function file_put_contents;
|
|
use function implode;
|
|
use function ksort;
|
|
use function preg_replace;
|
|
use function preg_replace_callback;
|
|
use function sprintf;
|
|
use function str_contains;
|
|
use function str_starts_with;
|
|
use function strlen;
|
|
use function trim;
|
|
|
|
use const PHP_EOL;
|
|
|
|
#[AsCommand(
|
|
name: 'update:postal-codes',
|
|
description: 'Update the list of postal codes in the PostalCode validator',
|
|
)]
|
|
final class UpdatePostalCodesCommand extends Command
|
|
{
|
|
private const string LIST_URL = 'https://download.geonames.org/export/dump/countryInfo.txt';
|
|
|
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
|
{
|
|
$io = new SymfonyStyle($input, $output);
|
|
|
|
$io->title('Updating postal codes list');
|
|
|
|
// Download the list
|
|
$io->section('Downloading list');
|
|
$io->text(sprintf('Fetching from: %s', self::LIST_URL));
|
|
|
|
$listContent = file_get_contents(self::LIST_URL);
|
|
if ($listContent === false) {
|
|
$io->error('Failed to download postal codes list');
|
|
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
$io->success('Downloaded successfully');
|
|
|
|
// Process the list
|
|
$io->section('Processing postal codes');
|
|
|
|
$lines = explode("\n", $listContent);
|
|
$postalCodes = [];
|
|
|
|
foreach ($lines as $line) {
|
|
$line = trim($line);
|
|
|
|
// Skip comments and empty lines
|
|
if ($line === '' || str_starts_with($line, '#')) {
|
|
continue;
|
|
}
|
|
|
|
// Split by tab
|
|
$parts = explode("\t", $line);
|
|
if (count($parts) < 15) {
|
|
continue;
|
|
}
|
|
|
|
$countryCode = $parts[0];
|
|
$countryFormat = $parts[13];
|
|
$countryRegex = trim($parts[14]);
|
|
|
|
if ($countryRegex === '') {
|
|
continue;
|
|
}
|
|
|
|
// Convert format
|
|
$countryFormat = preg_replace_callback('/(#+|@+)/', static function ($matches) {
|
|
$length = strlen($matches[0]);
|
|
$regex = str_contains($matches[0], '#') ? '\d' : '\w';
|
|
if ($length > 1) {
|
|
$regex .= '{' . $length . '}';
|
|
}
|
|
|
|
return $regex;
|
|
}, $countryFormat);
|
|
|
|
$postalCodes[$countryCode] = ['/^' . $countryFormat . '$/', '/' . $countryRegex . '/'];
|
|
}
|
|
|
|
ksort($postalCodes);
|
|
|
|
// Create the data file
|
|
$dataFilename = dirname(__DIR__, 2) . '/data/domain/postal-code.php';
|
|
|
|
$fileContent = implode(PHP_EOL, [
|
|
'<?php declare(strict_types=1);',
|
|
'// Copyright (c) https://download.geonames.org/export/dump/countryInfo.txt',
|
|
'// SPDX-License-Identifier: CC-BY-4.0',
|
|
'return ' . preg_replace('/\\\([dws])/', '\\1', VarExporter::export($postalCodes)) . ';' . PHP_EOL,
|
|
]);
|
|
|
|
// Write the data file
|
|
if (file_put_contents($dataFilename, $fileContent) === false) {
|
|
$io->error('Failed to write data file');
|
|
|
|
return Command::FAILURE;
|
|
}
|
|
|
|
$io->success(sprintf('Updated %s successfully', basename($dataFilename)));
|
|
$io->text(sprintf('Total postal codes: %d', count($postalCodes)));
|
|
|
|
return Command::SUCCESS;
|
|
}
|
|
}
|