Skip to content

Instantly share code, notes, and snippets.

@tassioauad
Created January 28, 2013 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tassioauad/4655897 to your computer and use it in GitHub Desktop.
Save tassioauad/4655897 to your computer and use it in GitHub Desktop.
Zend Framework 2 Form Validator for Brazillian CPF and CNPJ
<?php
namespace Application\Validator;
use Zend\Validator\AbstractValidator;
class CpfCnpjValidator extends AbstractValidator
{
const CPF_INVALID = "CPFInvalido";
const CNPJ_INVALID = "CNPJInvalido";
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = array(
self::CPF_INVALID => "CPF inválido.",
self::CNPJ_INVALID => "CNPJ inválido.",
);
/**
* Returns true if and only if $value meets the validation requirements
*
* If $value fails validation, then this method returns false, and
* getMessages() will return an array of messages that explain why the
* validation failed.
*
* @param mixed $value
* @return boolean
* @throws Exception\RuntimeException If validation of $value is impossible
*/
public function isValid($value)
{
$cpfValidator = new CpfValidator();
if ($cpfValidator->isValid($value)) {
return true;
}
$cnpjValidator = new CnpjValidator();
if ($cnpjValidator->isValid($value)) {
return true;
}
if (strlen($value) == 14) {
$this->error(self::CPF_INVALID);
} elseif (strlen($value) == 18) {
$this->error(self::CNPJ_INVALID);
}
return false;
}
}
<?php
namespace Application\Validator;
use Zend\Validator\AbstractValidator;
class CpfValidator extends AbstractValidator
{
const INVALID = "CPFInvalido.";
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = array(
self::INVALID => "CPF Inválido.",
);
/**
* Returns true if and only if $value meets the validation requirements
*
* If $value fails validation, then this method returns false, and
* getMessages() will return an array of messages that explain why the
* validation failed.
*
* @param mixed $value
* @return boolean
* @throws Exception\RuntimeException If validation of $value is impossible
*/
public function isValid($value)
{
$cpf = $this->trimCPF($value);
if (!$this->respectsRegularExpression($cpf)) {
$this->error(self::INVALID);
return false;
}
if (!$this->applyingCpfRules($cpf)) {
$this->error(self::INVALID);
return false;
}
return true;
}
/**
* @param $cpf
* @return string
*/
private function trimCPF($cpf)
{
$cpf = preg_replace('/[.,-]/', '', $cpf);
return $cpf;
}
/**
* @param $cpf
* @return bool
*/
private function respectsRegularExpression($cpf)
{
$regularExpression = "[0-9]{3}\\.?[0-9]{3}\\.?[0-9]{3}-?[0-9]{2}";
if (!@ereg("^" . $regularExpression . "\$", $cpf)) {
return false;
}
return true;
}
/**
* @param $cpf
* @return bool
*/
private function applyingCpfRules($cpf)
{
if (
strlen($cpf)!= 11 || $cpf == "00000000000" || $cpf == "11111111111" ||
$cpf == "22222222222" || $cpf == "33333333333" || $cpf == "44444444444" ||
$cpf == "55555555555" || $cpf == "66666666666" || $cpf == "77777777777" ||
$cpf == "88888888888" || $cpf == "99999999999"
) {
return false;
}
$soma = 0;
for ($i=0; $i < 9; $i ++) {
$soma += (int) (substr($cpf, $i, 1)) * (10 - $i);
}
$resto = 11 - ($soma % 11);
if ($resto == 10 || $resto == 11) {
$resto = 0;
}
if ($resto != (int) (substr($cpf, 9, 1))) {
return false;
}
$soma = 0;
for ($i = 0; $i < 10; $i ++) {
$soma += (int) (substr($cpf, $i, 1)) * (11 - $i);
}
$resto = 11 - ($soma % 11);
if ($resto == 10 || $resto == 11) {
$resto = 0;
}
if ($resto != (int) (substr($cpf, 10, 1))) {
return false;
}
return true;
}
}
<?php
namespace Application\Validator;
use Zend\Validator\AbstractValidator;
class CnpjValidator extends AbstractValidator
{
const INVALID = "CNPJInvalido.";
/**
* Validation failure message template definitions
*
* @var array
*/
protected $messageTemplates = array(
self::INVALID => "CNPJ Inválido.",
);
/**
* Returns true if and only if $value meets the validation requirements
*
* If $value fails validation, then this method returns false, and
* getMessages() will return an array of messages that explain why the
* validation failed.
*
* @param mixed $value
* @return boolean
* @throws Exception\RuntimeException If validation of $value is impossible
*/
public function isValid($value)
{
$cnpj = $this->trimCNPJ($value);
if ($this->respectsRegularExpression($cnpj) != 1) {
$this->error(self::INVALID);
return false;
} else {
$x = strlen($cnpj) - 2;
if ($this->applyingCnpjRules($cnpj, $x) == 1) {
$x = strlen($cnpj) - 1;
if ($this->applyingCnpjRules($cnpj, $x) == 1) {
return true;
} else {
$this->error(self::INVALID);
return false;
}
} else {
$this->error(self::INVALID);
return false;
}
}
}
/**
* @param $cnpj
* @return string
*/
private function trimCNPJ($cnpj)
{
$cnpj = preg_replace('/[.,-]/', '', $cnpj);
return $cnpj;
}
/**
* @param $cnpj
* @return bool
*/
private function respectsRegularExpression($cnpj)
{
$regularExpression = "[0-9]{2,3}\\.?[0-9]{3}\\.?[0-9]{3}/?[0-9]{4}-?[0-9]{2}";
if (!@ereg("^" . $regularExpression . "\$", $cnpj)) {
return false;
}
return true;
}
/**
* @param $cnpj
* @param $x
* @return bool
*/
private function applyingCnpjRules($cnpj, $x)
{
$VerCNPJ = 0;
$ind = 2;
for ($y = $x; $y>0; $y--) {
$VerCNPJ += (int) substr($cnpj, $y-1, 1) * $ind;
if ($ind > 8) {
$ind = 2;
} else {
$ind++;
}
}
$VerCNPJ %= 11;
if (($VerCNPJ == 0) || ($VerCNPJ == 1)) {
$VerCNPJ = 0;
} else {
$VerCNPJ = 11 - $VerCNPJ;
}
if ($VerCNPJ != (int) substr($cnpj, $x, 1)) {
return false;
} else {
return true;
}
}
}
@caferrari
Copy link

@ereg("^" . $regularExpression . "$", $cnpj)

?

@marciodojr
Copy link

Isn't better to trim only after checks if cpf/cnpj respects the regular expressions?

e. g.

if (!$this->respectsRegularExpression($value)) {
$this->error(self::INVALID);
return false;
}
$cpf = $this->trimCPF($value);

@marciodojr
Copy link

maybe replace

!@ereg("^" . $regularExpression . "$" ...
by
!preg_match('#' . $regularExpression . '#', ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment