Skip to content

Commit

Permalink
#66 custom warnings (#94)
Browse files Browse the repository at this point in the history
close #66 custom warnings
  • Loading branch information
egulias committed Apr 28, 2016
1 parent d29b96b commit fa5dd33
Show file tree
Hide file tree
Showing 30 changed files with 549 additions and 248 deletions.
8 changes: 5 additions & 3 deletions src/Egulias/EmailValidator/EmailParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Egulias\EmailValidator\Exception\NoLocalPart;
use Egulias\EmailValidator\Parser\DomainPart;
use Egulias\EmailValidator\Parser\LocalPart;
use Egulias\EmailValidator\Warning\EmailTooLong;

/**
* EmailParser
Expand All @@ -16,7 +17,7 @@ class EmailParser
{
const EMAIL_MAX_LENGTH = 254;

protected $warnings = array();
protected $warnings;
protected $domainPart = '';
protected $localPart = '';
protected $lexer;
Expand All @@ -28,6 +29,7 @@ public function __construct(EmailLexer $lexer)
$this->lexer = $lexer;
$this->localPartParser = new LocalPart($this->lexer);
$this->domainPartParser = new DomainPart($this->lexer);
$this->warnings = new \SplObjectStorage();
}

/**
Expand Down Expand Up @@ -59,8 +61,8 @@ public function getWarnings()
{
$localPartWarnings = $this->localPartParser->getWarnings();
$domainPartWarnings = $this->domainPartParser->getWarnings();

$this->warnings = array_merge($localPartWarnings, $domainPartWarnings);

$this->addLongEmailWarning($this->localPart, $this->domainPart);

return $this->warnings;
Expand Down Expand Up @@ -96,7 +98,7 @@ protected function hasAtToken()
protected function addLongEmailWarning($localPart, $parsedDomainPart)
{
if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) {
$this->warnings[] = EmailValidator::RFC5322_TOOLONG;
$this->warnings[EmailTooLong::CODE] = new EmailTooLong();
}
}
}
73 changes: 24 additions & 49 deletions src/Egulias/EmailValidator/EmailValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

namespace Egulias\EmailValidator;

use Egulias\EmailValidator\InvalidEmail;
use Egulias\EmailValidator\Warning\NoDNSMXRecord;
use Egulias\EmailValidator\Warning\NoDNSRecord;
use Egulias\EmailValidator\Warning\DomainLiteral;
use Egulias\EmailValidator\Warning\TLD;

/**
* EmailValidator
Expand All @@ -12,39 +15,9 @@
class EmailValidator
{
const ERR_DEPREC_REACHED = 151;
const ERR_UNOPENEDCOMMENT = 152;
const RFC5321_TLD = 9;
const RFC5321_TLDNUMERIC = 10;
const RFC5321_QUOTEDSTRING = 11;
const RFC5321_ADDRESSLITERAL = 12;
const RFC5321_IPV6DEPRECATED = 13;
const CFWS_COMMENT = 17;
const CFWS_FWS = 18;
const DEPREC_LOCALPART = 33;
const DEPREC_FWS = 34;
const DEPREC_QTEXT = 35;
const DEPREC_QP = 36;
const DEPREC_COMMENT = 37;
const DEPREC_CTEXT = 38;
const DEPREC_CFWS_NEAR_AT = 49;
const RFC5322_LOCAL_TOOLONG = 64;
const RFC5322_LABEL_TOOLONG = 63;
const RFC5322_DOMAIN = 65;
const RFC5322_TOOLONG = 66;
const RFC5322_DOMAIN_TOOLONG = 255;
const RFC5322_DOMAINLITERAL = 70;
const RFC5322_DOMLIT_OBSDTEXT = 71;
const RFC5322_IPV6_GRPCOUNT = 72;
const RFC5322_IPV6_2X2XCOLON = 73;
const RFC5322_IPV6_BADCHAR = 74;
const RFC5322_IPV6_MAXGRPS = 75;
const RFC5322_IPV6_COLONSTRT = 76;
const RFC5322_IPV6_COLONEND = 77;
const DNSWARN_NO_MX_RECORD = 5;
const DNSWARN_NO_RECORD = 6;

protected $parser;
protected $warnings = array();
protected $warnings;
protected $error;
protected $threshold = 255;

Expand Down Expand Up @@ -72,11 +45,11 @@ public function isValid($email, $checkDNS = false, $strict = false)
$dns = $this->checkDNS();
}

if ($this->hasWarnings() && ((int) max($this->warnings) > $this->threshold)) {
$this->error = self::ERR_DEPREC_REACHED;

return false;
}
// if ($this->hasWarnings() && ((int) max($this->warnings) > $this->threshold)) {
// $this->error = self::ERR_DEPREC_REACHED;
//
// return false;
// }

return !$strict || (!$this->hasWarnings() && $dns);
}
Expand Down Expand Up @@ -128,25 +101,27 @@ public function getThreshold()
protected function checkDNS()
{
$checked = true;

$result = checkdnsrr(trim($this->parser->getParsedDomainPart()), 'MX');

if (!$result) {
$this->warnings[] = self::DNSWARN_NO_RECORD;
$checked = false;
$this->addTLDWarnings();
$MXresult = checkdnsrr(trim($this->parser->getParsedDomainPart()), 'MX');

if (!$MXresult) {
$this->warnings[NoDNSMXRecord::CODE] = new NoDNSMXRecord();
$Aresult = checkdnsrr(trim($this->parser->getParsedDomainPart()), 'A');
if (!$Aresult) {
$this->warnings[NoDNSRecord::CODE] = new NoDNSRecord();
$checked = false;
$this->addTLDWarnings();
}
}

return $checked;
}

protected function addTLDWarnings()
{
if (!in_array(self::DNSWARN_NO_RECORD, $this->warnings) &&
!in_array(self::DNSWARN_NO_MX_RECORD, $this->warnings) &&
in_array(self::RFC5322_DOMAINLITERAL, $this->warnings)
if (!isset($this->warnings[NoDNSMXRecord::CODE]) &&
!isset($this->warnings[NoDNSRecord::CODE]) &&
isset($this->warnings[DomainLiteral::CODE])
) {
$this->warnings[] = self::RFC5321_TLD;
$this->warnings[TLD::CODE] = new TLD();
}
}
}
56 changes: 35 additions & 21 deletions src/Egulias/EmailValidator/Parser/DomainPart.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@
use Egulias\EmailValidator\Exception\NoDomainPart;
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Exception\UnopenedComment;
use Egulias\EmailValidator\Warning\AddressLiteral;
use Egulias\EmailValidator\Warning\CFWSWithFWS;
use Egulias\EmailValidator\Warning\DeprecatedComment;
use Egulias\EmailValidator\Warning\DomainLiteral;
use Egulias\EmailValidator\Warning\DomainTooLong;
use Egulias\EmailValidator\Warning\IPV6BadChar;
use Egulias\EmailValidator\Warning\IPV6ColonEnd;
use Egulias\EmailValidator\Warning\IPV6ColonStart;
use Egulias\EmailValidator\Warning\IPV6Deprecated;
use Egulias\EmailValidator\Warning\IPV6DoubleColon;
use Egulias\EmailValidator\Warning\IPV6GroupCount;
use Egulias\EmailValidator\Warning\IPV6MaxGroups;
use Egulias\EmailValidator\Warning\LabelTooLong;
use Egulias\EmailValidator\Warning\ObsoleteDTEXT;

class DomainPart extends Parser
{
Expand All @@ -37,7 +51,7 @@ public function parse($domainPart)
}

if ($this->lexer->token['type'] === EmailLexer::S_OPENPARENTHESIS) {
$this->warnings[] = EmailValidator::DEPREC_COMMENT;
$this->warnings[DeprecatedComment::CODE] = new DeprecatedComment();
$this->parseDomainComments();
}

Expand All @@ -53,7 +67,7 @@ public function parse($domainPart)
throw new DomainHyphened();
}
if ($length > self::DOMAIN_MAX_LENGTH) {
$this->warnings[] = EmailValidator::RFC5322_DOMAIN_TOOLONG;
$this->warnings[DomainTooLong::CODE] = new DomainTooLong();
}
if ($prev['type'] === EmailLexer::S_CR) {
throw new CRLFAtTheEnd();
Expand All @@ -70,7 +84,7 @@ public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
{
$prev = $this->lexer->getPrevious();
if ($prev['type'] === EmailLexer::S_COLON) {
$this->warnings[] = EmailValidator::RFC5322_IPV6_COLONEND;
$this->warnings[IPV6ColonEnd::CODE] = new IPV6ColonEnd();
}

$IPv6 = substr($addressLiteral, 5);
Expand All @@ -80,19 +94,19 @@ public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
$colons = strpos($IPv6, '::');

if (count(preg_grep('/^[0-9A-Fa-f]{0,4}$/', $matchesIP, PREG_GREP_INVERT)) !== 0) {
$this->warnings[] = EmailValidator::RFC5322_IPV6_BADCHAR;
$this->warnings[IPV6BadChar::CODE] = new IPV6BadChar();
}

if ($colons === false) {
// We need exactly the right number of groups
if ($groupCount !== $maxGroups) {
$this->warnings[] = EmailValidator::RFC5322_IPV6_GRPCOUNT;
$this->warnings[IPV6GroupCount::CODE] = new IPV6GroupCount();
}
return;
}

if ($colons !== strrpos($IPv6, '::')) {
$this->warnings[] = EmailValidator::RFC5322_IPV6_2X2XCOLON;
$this->warnings[IPV6DoubleColon::CODE] = new IPV6DoubleColon();
return;
}

Expand All @@ -103,9 +117,9 @@ public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
}

if ($groupCount > $maxGroups) {
$this->warnings[] = EmailValidator::RFC5322_IPV6_MAXGRPS;
$this->warnings[IPV6MaxGroups::CODE] = new IPV6MaxGroups();
} elseif ($groupCount === $maxGroups) {
$this->warnings[] = EmailValidator::RFC5321_IPV6DEPRECATED;
$this->warnings[IPV6Deprecated::CODE] = new IPV6Deprecated();
}
}

Expand Down Expand Up @@ -160,13 +174,13 @@ protected function doParseDomainPart()
protected function parseDomainLiteral()
{
if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
$this->warnings[] = EmailValidator::RFC5322_IPV6_COLONSTRT;
$this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart();
}
if ($this->lexer->isNextToken(EmailLexer::S_IPV6TAG)) {
$lexer = clone $this->lexer;
$lexer->moveNext();
if ($lexer->isNextToken(EmailLexer::S_DOUBLECOLON)) {
$this->warnings[] = EmailValidator::RFC5322_IPV6_COLONSTRT;
$this->warnings[IPV6ColonStart::CODE] = new IPV6ColonStart();
}
}

Expand All @@ -186,7 +200,7 @@ protected function doParseDomainLiteral()
$this->lexer->token['type'] === EmailLexer::C_DEL ||
$this->lexer->token['type'] === EmailLexer::S_LF
) {
$this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT;
$this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT();
}

if ($this->lexer->isNextTokenAny(array(EmailLexer::S_OPENQBRACKET, EmailLexer::S_OPENBRACKET))) {
Expand All @@ -196,7 +210,7 @@ protected function doParseDomainLiteral()
if ($this->lexer->isNextTokenAny(
array(EmailLexer::S_HTAB, EmailLexer::S_SP, $this->lexer->token['type'] === EmailLexer::CRLF)
)) {
$this->warnings[] = EmailValidator::CFWS_FWS;
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
$this->parseFWS();
}

Expand All @@ -205,7 +219,7 @@ protected function doParseDomainLiteral()
}

if ($this->lexer->token['type'] === EmailLexer::S_BACKSLASH) {
$this->warnings[] = EmailValidator::RFC5322_DOMLIT_OBSDTEXT;
$this->warnings[ObsoleteDTEXT::CODE] = new ObsoleteDTEXT();
$addressLiteral .= $this->lexer->token['value'];
$this->lexer->moveNext();
$this->validateQuotedPair();
Expand All @@ -229,11 +243,11 @@ protected function doParseDomainLiteral()
}

if (!$IPv6TAG) {
$this->warnings[] = EmailValidator::RFC5322_DOMAINLITERAL;
$this->warnings[DomainLiteral::CODE] = new DomainLiteral();
return $addressLiteral;
}

$this->warnings[] = EmailValidator::RFC5321_ADDRESSLITERAL;
$this->warnings[AddressLiteral::CODE] = new AddressLiteral();

$this->checkIPV6Tag($addressLiteral);

Expand All @@ -246,14 +260,14 @@ protected function checkIPV4Tag($addressLiteral)

// Extract IPv4 part from the end of the address-literal (if there is one)
if (preg_match(
'/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/',
$addressLiteral,
$matchesIP
) > 0
'/\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/',
$addressLiteral,
$matchesIP
) > 0
) {
$index = strrpos($addressLiteral, $matchesIP[0]);
if ($index === 0) {
$this->warnings[] = EmailValidator::RFC5321_ADDRESSLITERAL;
$this->warnings[AddressLiteral::CODE] = new AddressLiteral();
return false;
}
// Convert IPv4 part to IPv6 format for further testing
Expand Down Expand Up @@ -319,7 +333,7 @@ protected function checkLabelLength($prev)
$prev['type'] === EmailLexer::GENERIC &&
strlen($prev['value']) > 63
) {
$this->warnings[] = EmailValidator::RFC5322_LABEL_TOOLONG;
$this->warnings[LabelTooLong::CODE] = new LabelTooLong();
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/Egulias/EmailValidator/Parser/LocalPart.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use Egulias\EmailValidator\EmailValidator;
use Egulias\EmailValidator\Exception\ExpectingATEXT;
use Egulias\EmailValidator\Exception\UnopenedComment;
use Egulias\EmailValidator\Warning\CFWSWithFWS;
use Egulias\EmailValidator\Warning\LocalTooLong;

class LocalPart extends Parser
{
Expand Down Expand Up @@ -58,8 +60,8 @@ public function parse($localPart)
}

$prev = $this->lexer->getPrevious();
if (strlen($prev['value']) > EmailValidator::RFC5322_LOCAL_TOOLONG) {
$this->warnings[] = EmailValidator::RFC5322_LOCAL_TOOLONG;
if (strlen($prev['value']) > LocalTooLong::LOCAL_PART_LENGTH) {
$this->warnings[LocalTooLong::CODE] = new LocalTooLong();
}
}

Expand All @@ -85,7 +87,7 @@ protected function parseDoubleQuote()
while ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE && $this->lexer->token) {
$parseAgain = false;
if (isset($special[$this->lexer->token['type']]) && $setSpecialsWarning) {
$this->warnings[] = EmailValidator::CFWS_FWS;
$this->warnings[CFWSWithFWS::CODE] = new CFWSWithFWS();
$setSpecialsWarning = false;
}

Expand Down
Loading

0 comments on commit fa5dd33

Please sign in to comment.