Exemplos Oficiais — packages/people
Implementações de referência para os contratos documentados em contracts.md. Utilize-as como ponto de partida ao criar pacotes próprios ou adaptar a validação para novos países.
CPF (Brasil) — BrCpfValidator
php
final class BrCpfValidator implements DocumentValidatorContract
{
public function key(): string
{
return 'br.cpf';
}
public function pattern(): string
{
return '/^\d{3}\.\d{3}\.\d{3}\-\d{2}$/';
}
public function normalize(string $document): string
{
return preg_replace('/\D/', '', $document);
}
public function validate(string $document): bool
{
$digits = $this->normalize($document);
if (strlen($digits) !== 11 || preg_match('/^(\\d)\\1{10}$/', $digits)) {
return false;
}
$calc = static function (array $numbers, int $factor): int {
$sum = 0;
foreach ($numbers as $number) {
$sum += $number * $factor--;
}
$result = ($sum * 10) % 11;
return $result === 10 ? 0 : $result;
};
$base = array_map('intval', str_split(substr($digits, 0, 9)));
$dv1 = $calc($base, 10);
$dv2 = $calc(array_merge($base, [$dv1]), 11);
return $digits[9] == $dv1 && $digits[10] == $dv2;
}
}- Armazene o regex padrão (
pattern()) em tabela de configurações para permitir edições posteriores. - Adicione testes com CPFs válidos e inválidos em
tests/Contracts/Document/BrCpfValidatorTest.php.
CNPJ (Brasil) — BrCnpjValidator
Segue lógica semelhante ao CPF, porém com 14 dígitos e pesos distintos. Recomenda-se extrair o cálculo dos dígitos verificadores para uma trait reutilizável (CalculatesBrazilianDv).
NIF Português — PtNifValidator
- Regex:
/^\d{9}$/. - Aplicar algoritmo de validação módulo 11.
- Permitir prefixos específicos (1, 2, 3, 5, 6, 8, 9) de acordo com a legislação.
Lookup de Endereço com ViaCEP — ViaCepProvider
php
final class ViaCepProvider implements AddressLookupContract
{
public function countryCode(): string
{
return 'BR';
}
public function lookupByPostalCode(string $postalCode): AddressDto
{
$normalized = preg_replace('/\D/', '', $postalCode);
$response = Http::get("https://viacep.com.br/ws/{$normalized}/json/");
if ($response->failed() || $response->json('erro')) {
return AddressDto::empty();
}
return new AddressDto(
street: $response['logradouro'] ?? '',
number: null,
district: $response['bairro'] ?? '',
city: $response['localidade'] ?? '',
state: $response['uf'] ?? '',
postalCode: $normalized,
country: 'BR'
);
}
}- Adicione cache (
Cache::remember) para reduzir chamadas. - Documente limites de uso conforme a política da API.
Normalizador de Telefone com libphonenumber — LibPhoneNumberNormalizer
php
final class LibPhoneNumberNormalizer implements ContactNormalizerContract
{
public function supports(string $type): bool
{
return $type === 'phone';
}
public function normalize(string $value): string
{
$util = PhoneNumberUtil::getInstance();
$phone = $util->parse($value, 'BR'); // padrão configurável
return $util->format($phone, PhoneNumberFormat::E164);
}
public function isValid(string $value): bool
{
try {
$util = PhoneNumberUtil::getInstance();
$phone = $util->parse($value, 'BR');
return $util->isValidNumber($phone);
} catch (\Throwable $e) {
return false;
}
}
}- Permita sobrescrever o país padrão via config (
people.contacts.default_region). - Adicione testes com números válidos/invalidos e cenários de exceção.
Normalizador de E-mail — DnsEmailNormalizer
supports('email').- Usa
Str::lower(trim($value)). - Valida com
filter_var($value, FILTER_VALIDATE_EMAIL)e consulta DNS MX (checkdnsrr). - Opcional: integra com serviços de verificação (Kickbox, ZeroBounce) via eventos.
Campos Customizados
Exemplo para student_id com máscara e cast para string.
php
final class StudentIdAttribute implements PersonAttributeContract
{
public function key(): string
{
return 'student_id';
}
public function rules(): array
{
return ['nullable', 'regex:/^[A-Z]{3}\-\d{4}$/'];
}
public function cast(mixed $value): ?string
{
return $value ? strtoupper((string) $value) : null;
}
}Checklist de Implementação
- [ ] Registrar contratos no service provider do pacote (
DocumentValidatorRegistry,AddressLookupRegistry). - [ ] Criar testes de contrato e snapshots para payloads normalizados.
- [ ] Documentar configuração (
config/people.php) e fornecer comandos Artisan para listar validadores. - [ ] Publicar exemplos na documentação oficial e manter changelog por implementação.