feat(phone): split phone number components into separate fields and update related models and resources

This commit is contained in:
2026-09-30 13:39:24 -03:00
parent 77dd0e2715
commit f3e226130f
6 changed files with 201 additions and 2 deletions

View File

@@ -0,0 +1,94 @@
<?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::table('phone_numbers', function (Blueprint $table): void {
$table->string('country_code', 8)->nullable()->default('+54');
$table->string('mobile_prefix', 4)->nullable()->default('9');
$table->string('area_code', 8)->nullable();
$table->string('local_number')->nullable();
});
DB::table('phone_numbers')->orderBy('id')->chunkById(100, function ($numbers): void {
foreach ($numbers as $phone) {
DB::table('phone_numbers')->where('id', $phone->id)
->update($this->components($phone->number));
}
});
Schema::table('phone_numbers', function (Blueprint $table): void {
$table->dropColumn('number');
});
}
public function down(): void
{
Schema::table('phone_numbers', function (Blueprint $table): void {
$table->string('number')->nullable();
});
DB::table('phone_numbers')->orderBy('id')->chunkById(100, function ($numbers): void {
foreach ($numbers as $phone) {
$parts = array_filter([
$phone->country_code,
$phone->mobile_prefix,
$phone->area_code,
$phone->local_number,
], fn ($part): bool => $part !== null && $part !== '');
DB::table('phone_numbers')->where('id', $phone->id)
->update(['number' => implode(' ', $parts)]);
}
});
Schema::table('phone_numbers', function (Blueprint $table): void {
$table->dropColumn(['country_code', 'mobile_prefix', 'area_code', 'local_number']);
});
}
/** @return array{country_code: ?string, mobile_prefix: ?string, area_code: ?string, local_number: string} */
private function components(string $number): array
{
$number = trim($number);
if (preg_match('/^(\+?\d{1,3})\s+(?:(9)\s+)?\(?(\d{2,5})\)?[\s-]+([\d\s-]+)$/', $number, $match)) {
return [
'country_code' => '+'.ltrim($match[1], '+'),
'mobile_prefix' => ($match[2] ?? '') ?: null,
'area_code' => $match[3],
'local_number' => preg_replace('/\D/', '', $match[4]),
];
}
if (preg_match('/^\(?(0\d{2,5})\)?[\s-]+([\d\s-]+)$/', $number, $match)) {
return [
'country_code' => null,
'mobile_prefix' => null,
'area_code' => $match[1],
'local_number' => preg_replace('/\D/', '', $match[2]),
];
}
if (preg_match('/^\+54(9?)(\d+)$/', $number, $match)) {
return [
'country_code' => '+54',
'mobile_prefix' => $match[1] === '9' ? '9' : null,
'area_code' => null,
'local_number' => $match[2],
];
}
return [
'country_code' => null,
'mobile_prefix' => null,
'area_code' => null,
'local_number' => $number,
];
}
};