| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- <?php
- namespace App\ValueObjects;
- use App\Casts\CpfCast;
- use Closure;
- use Illuminate\Contracts\Database\Eloquent\Castable;
- use InvalidArgumentException;
- use JsonSerializable;
- use Stringable;
- final readonly class Cpf implements Castable, JsonSerializable, Stringable
- {
- private string $value;
- public function __construct(string $value)
- {
- $digits = preg_replace('/\D/', '', $value);
- if ($digits === null || ! self::isValid($digits)) {
- throw new InvalidArgumentException(__('validation.cpf'));
- }
- $this->value = $digits;
- }
- public static function castUsing(array $arguments): string
- {
- return CpfCast::class;
- }
- public static function rule(): Closure
- {
- return static function (string $attribute, mixed $value, Closure $fail): void {
- if (! is_string($value)) {
- $fail(__('validation.cpf'));
- return;
- }
- try {
- new self($value);
- } catch (InvalidArgumentException) {
- $fail(__('validation.cpf'));
- }
- };
- }
- public function value(): string
- {
- return $this->value;
- }
- public function formatted(): string
- {
- return preg_replace(
- '/(\d{3})(\d{3})(\d{3})(\d{2})/',
- '$1.$2.$3-$4',
- $this->value,
- );
- }
- public function __toString(): string
- {
- return $this->value;
- }
- public function jsonSerialize(): string
- {
- return $this->value;
- }
- private static function isValid(string $digits): bool
- {
- if (strlen($digits) !== 11 || preg_match('/^(\d)\1{10}$/', $digits)) {
- return false;
- }
- for ($position = 9; $position < 11; $position++) {
- $sum = 0;
- for ($index = 0; $index < $position; $index++) {
- $sum += (int) $digits[$index] * (($position + 1) - $index);
- }
- $checkDigit = (($sum * 10) % 11) % 10;
- if ((int) $digits[$position] !== $checkDigit) {
- return false;
- }
- }
- return true;
- }
- }
|