Last active
June 29, 2021 23:31
-
-
Save sahibalejandro/8d77e74463a825f3cbd8 to your computer and use it in GitHub Desktop.
Laravel's RFC Validator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @author Sahib J. Leo <sahib@sahib.io> | |
* Date: 11/24/15 8:53 AM | |
*/ | |
namespace App\Validation; | |
class RfcValidator | |
{ | |
/** | |
* Regla de validación para un RFC. | |
* | |
* @param string $attribute | |
* @param string $value | |
* @param array $parameters | |
* @param \Illuminate\Contracts\Validation\Validator $validator | |
* @return boolean | |
*/ | |
public function validate($attribute, $value, $parameters, $validator) | |
{ | |
if (!$this->correctLenght($value)) { | |
return false; | |
} | |
if (!preg_match($this->pattern($value), $value, $matches)) { | |
return false; | |
} | |
if (!$this->hasValidDate($matches)) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Verifica que el RFC tenga una longitud correcta. | |
* | |
* @param string $rfc | |
* @return bool | |
*/ | |
private function correctLenght($rfc) | |
{ | |
$length = mb_strlen($rfc); | |
// El RFC debe ser de 12 letras para personas morales y 13 para personas | |
// físicas, cualquier longitud fuera de ese rango resulta en un RFC | |
// inválido. | |
return $length >= 12 && $length <= 13; | |
} | |
/** | |
* Devuelve el patrón que debe ser usado por preg_match() para el RFC en | |
* cuestión. | |
* | |
* @see https://es.wikipedia.org/wiki/Registro_Federal_de_Contribuyentes_(México) | |
* @param string $rfc | |
* @return string | |
*/ | |
private function pattern($rfc) | |
{ | |
$length = mb_strlen($rfc); | |
// El RFC debe comenzar con 3 letras para personas morales, o con 4 | |
// letras para personas físicas. | |
$lettersLength = ($length == 12) ? 3 : 4; | |
return '/^[A-ZÑ&]{' . $lettersLength . '}([0-9]{2})([0-1][0-9])([0-3][0-9])[A-Z0-9]{2}[0-9A]$/iu'; | |
} | |
/** | |
* Verifica si el RFC tiene una fecha válida a partir de los 'match' del | |
* resultado de preg_match(). | |
* | |
* @param array $matches | |
* @return bool | |
*/ | |
private function hasValidDate($matches) | |
{ | |
// Extraemos los datos de la fecha para poder validar su integridad. | |
$year = (int)$matches[1]; | |
$month = (int)$matches[2]; | |
$day = (int)$matches[3]; | |
// Si el año es menor a 70 se asume que es después del año 2000. | |
$year < 70 ? $year += 2000 : $year += 1900; | |
return checkdate($month, $day, $year); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment