mirror of
https://github.com/egulias/EmailValidator.git
synced 2026-09-01 21:19:25 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e834eea530 |
+11
@@ -8,26 +8,37 @@ matrix:
|
|||||||
- php: 5.5
|
- php: 5.5
|
||||||
dist: trusty
|
dist: trusty
|
||||||
- php: 5.6
|
- php: 5.6
|
||||||
|
env:
|
||||||
dist: xenial
|
dist: xenial
|
||||||
- php: 7.0
|
- php: 7.0
|
||||||
dist: xenial
|
dist: xenial
|
||||||
- php: 7.1
|
- php: 7.1
|
||||||
|
env:
|
||||||
|
- psalm=yes
|
||||||
dist: bionic
|
dist: bionic
|
||||||
- php: 7.2
|
- php: 7.2
|
||||||
|
env:
|
||||||
|
- psalm=yes
|
||||||
dist: bionic
|
dist: bionic
|
||||||
- php: 7.3
|
- php: 7.3
|
||||||
dist: bionic
|
dist: bionic
|
||||||
|
env:
|
||||||
|
- psalm=yes
|
||||||
- php: 7.4
|
- php: 7.4
|
||||||
|
env:
|
||||||
|
- psalm=yes
|
||||||
dist: bionic
|
dist: bionic
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- if [ "$deps" = "low" ]; then composer update --prefer-lowest; else composer install; fi
|
- if [ "$deps" = "low" ]; then composer update --prefer-lowest; else composer install; fi
|
||||||
|
- if [ "$psalm" = "yes" ]; then composer require --dev vimeo/psalm; fi
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- mkdir -p build/logs
|
- mkdir -p build/logs
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
|
- vendor/bin/phpunit --coverage-clover build/logs/clover.xml
|
||||||
|
- if [ "$psalm" = "yes" ]; then vendor/bin/psalm; fi
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
- php vendor/bin/coveralls
|
- php vendor/bin/coveralls
|
||||||
|
|||||||
@@ -73,10 +73,37 @@ class EmailLexer extends AbstractLexer
|
|||||||
'\0' => self::C_NUL,
|
'\0' => self::C_NUL,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
protected $hasInvalidTokens = false;
|
protected $hasInvalidTokens = false;
|
||||||
|
|
||||||
protected $previous;
|
/**
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @psalm-var array{value:string, type:null|int, position:int}|array<empty, empty>
|
||||||
|
*/
|
||||||
|
protected $previous = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The last matched/seen token.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
* @psalm-var array{value:string, type:null|int, position:int}
|
||||||
|
*/
|
||||||
|
public $token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The next token in the input.
|
||||||
|
*
|
||||||
|
* @var array|null
|
||||||
|
*/
|
||||||
|
public $lookahead;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-var array{value:'', type:null, position:0}
|
||||||
|
*/
|
||||||
private static $nullToken = [
|
private static $nullToken = [
|
||||||
'value' => '',
|
'value' => '',
|
||||||
'type' => null,
|
'type' => null,
|
||||||
@@ -86,6 +113,7 @@ class EmailLexer extends AbstractLexer
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->previous = $this->token = self::$nullToken;
|
$this->previous = $this->token = self::$nullToken;
|
||||||
|
$this->lookahead = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,15 +126,20 @@ class EmailLexer extends AbstractLexer
|
|||||||
$this->previous = $this->token = self::$nullToken;
|
$this->previous = $this->token = self::$nullToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public function hasInvalidTokens()
|
public function hasInvalidTokens()
|
||||||
{
|
{
|
||||||
return $this->hasInvalidTokens;
|
return $this->hasInvalidTokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $type
|
* @param int $type
|
||||||
* @throws \UnexpectedValueException
|
* @throws \UnexpectedValueException
|
||||||
* @return boolean
|
* @return boolean
|
||||||
|
*
|
||||||
|
* @psalm-suppress InvalidScalarArgument
|
||||||
*/
|
*/
|
||||||
public function find($type)
|
public function find($type)
|
||||||
{
|
{
|
||||||
@@ -122,7 +155,7 @@ class EmailLexer extends AbstractLexer
|
|||||||
/**
|
/**
|
||||||
* getPrevious
|
* getPrevious
|
||||||
*
|
*
|
||||||
* @return array token
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getPrevious()
|
public function getPrevious()
|
||||||
{
|
{
|
||||||
@@ -196,6 +229,11 @@ class EmailLexer extends AbstractLexer
|
|||||||
return self::GENERIC;
|
return self::GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $value
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function isValid($value)
|
protected function isValid($value)
|
||||||
{
|
{
|
||||||
if (isset($this->charValue[$value])) {
|
if (isset($this->charValue[$value])) {
|
||||||
|
|||||||
@@ -17,11 +17,33 @@ class EmailParser
|
|||||||
{
|
{
|
||||||
const EMAIL_MAX_LENGTH = 254;
|
const EMAIL_MAX_LENGTH = 254;
|
||||||
|
|
||||||
protected $warnings;
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $warnings = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $domainPart = '';
|
protected $domainPart = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $localPart = '';
|
protected $localPart = '';
|
||||||
|
/**
|
||||||
|
* @var EmailLexer
|
||||||
|
*/
|
||||||
protected $lexer;
|
protected $lexer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LocalPart
|
||||||
|
*/
|
||||||
protected $localPartParser;
|
protected $localPartParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var DomainPart
|
||||||
|
*/
|
||||||
protected $domainPartParser;
|
protected $domainPartParser;
|
||||||
|
|
||||||
public function __construct(EmailLexer $lexer)
|
public function __construct(EmailLexer $lexer)
|
||||||
@@ -29,7 +51,6 @@ class EmailParser
|
|||||||
$this->lexer = $lexer;
|
$this->lexer = $lexer;
|
||||||
$this->localPartParser = new LocalPart($this->lexer);
|
$this->localPartParser = new LocalPart($this->lexer);
|
||||||
$this->domainPartParser = new DomainPart($this->lexer);
|
$this->domainPartParser = new DomainPart($this->lexer);
|
||||||
$this->warnings = new \SplObjectStorage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +78,9 @@ class EmailParser
|
|||||||
return array('local' => $this->localPart, 'domain' => $this->domainPart);
|
return array('local' => $this->localPart, 'domain' => $this->domainPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Warning\Warning[]
|
||||||
|
*/
|
||||||
public function getWarnings()
|
public function getWarnings()
|
||||||
{
|
{
|
||||||
$localPartWarnings = $this->localPartParser->getWarnings();
|
$localPartWarnings = $this->localPartParser->getWarnings();
|
||||||
@@ -68,11 +92,17 @@ class EmailParser
|
|||||||
return $this->warnings;
|
return $this->warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getParsedDomainPart()
|
public function getParsedDomainPart()
|
||||||
{
|
{
|
||||||
return $this->domainPart;
|
return $this->domainPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
*/
|
||||||
protected function setParts($email)
|
protected function setParts($email)
|
||||||
{
|
{
|
||||||
$parts = explode('@', $email);
|
$parts = explode('@', $email);
|
||||||
@@ -80,6 +110,9 @@ class EmailParser
|
|||||||
$this->localPart = $parts[0];
|
$this->localPart = $parts[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function hasAtToken()
|
protected function hasAtToken()
|
||||||
{
|
{
|
||||||
$this->lexer->moveNext();
|
$this->lexer->moveNext();
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ class EmailValidator
|
|||||||
private $lexer;
|
private $lexer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var Warning\Warning[]
|
||||||
*/
|
*/
|
||||||
protected $warnings;
|
protected $warnings = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var InvalidEmail
|
* @var InvalidEmail|null
|
||||||
*/
|
*/
|
||||||
protected $error;
|
protected $error;
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ class EmailValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return InvalidEmail
|
* @return InvalidEmail|null
|
||||||
*/
|
*/
|
||||||
public function getError()
|
public function getError()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ use Egulias\EmailValidator\Warning\TLD;
|
|||||||
class DomainPart extends Parser
|
class DomainPart extends Parser
|
||||||
{
|
{
|
||||||
const DOMAIN_MAX_LENGTH = 254;
|
const DOMAIN_MAX_LENGTH = 254;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $domainPart = '';
|
protected $domainPart = '';
|
||||||
|
|
||||||
public function parse($domainPart)
|
public function parse($domainPart)
|
||||||
@@ -95,11 +99,18 @@ class DomainPart extends Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function getDomainPart()
|
public function getDomainPart()
|
||||||
{
|
{
|
||||||
return $this->domainPart;
|
return $this->domainPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $addressLiteral
|
||||||
|
* @param int $maxGroups
|
||||||
|
*/
|
||||||
public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
|
public function checkIPV6Tag($addressLiteral, $maxGroups = 8)
|
||||||
{
|
{
|
||||||
$prev = $this->lexer->getPrevious();
|
$prev = $this->lexer->getPrevious();
|
||||||
@@ -143,6 +154,9 @@ class DomainPart extends Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
protected function doParseDomainPart()
|
protected function doParseDomainPart()
|
||||||
{
|
{
|
||||||
$domain = '';
|
$domain = '';
|
||||||
@@ -189,7 +203,7 @@ class DomainPart extends Parser
|
|||||||
return $domain;
|
return $domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkNotAllowedChars($token)
|
private function checkNotAllowedChars(array $token)
|
||||||
{
|
{
|
||||||
$notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
|
$notAllowed = [EmailLexer::S_BACKSLASH => true, EmailLexer::S_SLASH=> true];
|
||||||
if (isset($notAllowed[$token['type']])) {
|
if (isset($notAllowed[$token['type']])) {
|
||||||
@@ -197,6 +211,9 @@ class DomainPart extends Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
protected function parseDomainLiteral()
|
protected function parseDomainLiteral()
|
||||||
{
|
{
|
||||||
if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
|
if ($this->lexer->isNextToken(EmailLexer::S_COLON)) {
|
||||||
@@ -213,6 +230,9 @@ class DomainPart extends Parser
|
|||||||
return $this->doParseDomainLiteral();
|
return $this->doParseDomainLiteral();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
protected function doParseDomainLiteral()
|
protected function doParseDomainLiteral()
|
||||||
{
|
{
|
||||||
$IPv6TAG = false;
|
$IPv6TAG = false;
|
||||||
@@ -280,6 +300,11 @@ class DomainPart extends Parser
|
|||||||
return $addressLiteral;
|
return $addressLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $addressLiteral
|
||||||
|
*
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
protected function checkIPV4Tag($addressLiteral)
|
protected function checkIPV4Tag($addressLiteral)
|
||||||
{
|
{
|
||||||
$matchesIP = array();
|
$matchesIP = array();
|
||||||
@@ -297,13 +322,13 @@ class DomainPart extends Parser
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Convert IPv4 part to IPv6 format for further testing
|
// Convert IPv4 part to IPv6 format for further testing
|
||||||
$addressLiteral = substr($addressLiteral, 0, $index) . '0:0';
|
$addressLiteral = substr($addressLiteral, 0, (int) $index) . '0:0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return $addressLiteral;
|
return $addressLiteral;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function checkDomainPartExceptions($prev)
|
protected function checkDomainPartExceptions(array $prev)
|
||||||
{
|
{
|
||||||
$invalidDomainTokens = array(
|
$invalidDomainTokens = array(
|
||||||
EmailLexer::S_DQUOTE => true,
|
EmailLexer::S_DQUOTE => true,
|
||||||
@@ -338,6 +363,9 @@ class DomainPart extends Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function hasBrackets()
|
protected function hasBrackets()
|
||||||
{
|
{
|
||||||
if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) {
|
if ($this->lexer->token['type'] !== EmailLexer::S_OPENBRACKET) {
|
||||||
@@ -353,7 +381,7 @@ class DomainPart extends Parser
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function checkLabelLength($prev)
|
protected function checkLabelLength(array $prev)
|
||||||
{
|
{
|
||||||
if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
|
if ($this->lexer->token['type'] === EmailLexer::S_DOT &&
|
||||||
$prev['type'] === EmailLexer::GENERIC &&
|
$prev['type'] === EmailLexer::GENERIC &&
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ namespace Egulias\EmailValidator\Parser;
|
|||||||
use Egulias\EmailValidator\Exception\DotAtEnd;
|
use Egulias\EmailValidator\Exception\DotAtEnd;
|
||||||
use Egulias\EmailValidator\Exception\DotAtStart;
|
use Egulias\EmailValidator\Exception\DotAtStart;
|
||||||
use Egulias\EmailValidator\EmailLexer;
|
use Egulias\EmailValidator\EmailLexer;
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
|
||||||
use Egulias\EmailValidator\Exception\ExpectingAT;
|
use Egulias\EmailValidator\Exception\ExpectingAT;
|
||||||
use Egulias\EmailValidator\Exception\ExpectingATEXT;
|
use Egulias\EmailValidator\Exception\ExpectingATEXT;
|
||||||
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
|
use Egulias\EmailValidator\Exception\UnclosedQuotedString;
|
||||||
@@ -67,6 +66,9 @@ class LocalPart extends Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function parseDoubleQuote()
|
protected function parseDoubleQuote()
|
||||||
{
|
{
|
||||||
$parseAgain = true;
|
$parseAgain = true;
|
||||||
@@ -118,7 +120,10 @@ class LocalPart extends Parser
|
|||||||
return $parseAgain;
|
return $parseAgain;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function isInvalidToken($token, $closingQuote)
|
/**
|
||||||
|
* @param bool $closingQuote
|
||||||
|
*/
|
||||||
|
protected function isInvalidToken(array $token, $closingQuote)
|
||||||
{
|
{
|
||||||
$forbidden = array(
|
$forbidden = array(
|
||||||
EmailLexer::S_COMMA,
|
EmailLexer::S_COMMA,
|
||||||
|
|||||||
@@ -21,8 +21,19 @@ use Egulias\EmailValidator\Warning\QuotedString;
|
|||||||
|
|
||||||
abstract class Parser
|
abstract class Parser
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Egulias\EmailValidator\Warning\Warning[]
|
||||||
|
*/
|
||||||
protected $warnings = [];
|
protected $warnings = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EmailLexer
|
||||||
|
*/
|
||||||
protected $lexer;
|
protected $lexer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
protected $openedParenthesis = 0;
|
protected $openedParenthesis = 0;
|
||||||
|
|
||||||
public function __construct(EmailLexer $lexer)
|
public function __construct(EmailLexer $lexer)
|
||||||
@@ -30,11 +41,17 @@ abstract class Parser
|
|||||||
$this->lexer = $lexer;
|
$this->lexer = $lexer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Egulias\EmailValidator\Warning\Warning[]
|
||||||
|
*/
|
||||||
public function getWarnings()
|
public function getWarnings()
|
||||||
{
|
{
|
||||||
return $this->warnings;
|
return $this->warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $str
|
||||||
|
*/
|
||||||
abstract public function parse($str);
|
abstract public function parse($str);
|
||||||
|
|
||||||
/** @return int */
|
/** @return int */
|
||||||
@@ -80,6 +97,9 @@ abstract class Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function isUnclosedComment()
|
protected function isUnclosedComment()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@@ -122,6 +142,9 @@ abstract class Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function isFWS()
|
protected function isFWS()
|
||||||
{
|
{
|
||||||
if ($this->escaped()) {
|
if ($this->escaped()) {
|
||||||
@@ -140,6 +163,9 @@ abstract class Parser
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function escaped()
|
protected function escaped()
|
||||||
{
|
{
|
||||||
$previous = $this->lexer->getPrevious();
|
$previous = $this->lexer->getPrevious();
|
||||||
@@ -154,6 +180,9 @@ abstract class Parser
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function warnEscaping()
|
protected function warnEscaping()
|
||||||
{
|
{
|
||||||
if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
|
if ($this->lexer->token['type'] !== EmailLexer::S_BACKSLASH) {
|
||||||
@@ -174,6 +203,11 @@ abstract class Parser
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $hasClosingQuote
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function checkDQUOTE($hasClosingQuote)
|
protected function checkDQUOTE($hasClosingQuote)
|
||||||
{
|
{
|
||||||
if ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE) {
|
if ($this->lexer->token['type'] !== EmailLexer::S_DQUOTE) {
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ class DNSCheckValidation implements EmailValidation
|
|||||||
private $warnings = [];
|
private $warnings = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var InvalidEmail
|
* @var InvalidEmail|null
|
||||||
*/
|
*/
|
||||||
private $error;
|
private $error;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
if (!extension_loaded('intl')) {
|
if (!function_exists('idn_to_ascii')) {
|
||||||
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
|
throw new \LogicException(sprintf('The %s class requires the Intl extension.', __CLASS__));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,6 +49,11 @@ class DNSCheckValidation implements EmailValidation
|
|||||||
return $this->warnings;
|
return $this->warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $host
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
protected function checkDNS($host)
|
protected function checkDNS($host)
|
||||||
{
|
{
|
||||||
$variant = INTL_IDNA_VARIANT_2003;
|
$variant = INTL_IDNA_VARIANT_2003;
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ use Exception;
|
|||||||
|
|
||||||
class EmptyValidationList extends \InvalidArgumentException
|
class EmptyValidationList extends \InvalidArgumentException
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param int $code
|
||||||
|
*/
|
||||||
public function __construct($code = 0, Exception $previous = null)
|
public function __construct($code = 0, Exception $previous = null)
|
||||||
{
|
{
|
||||||
parent::__construct("Empty validation list is not allowed", $code, $previous);
|
parent::__construct("Empty validation list is not allowed", $code, $previous);
|
||||||
|
|||||||
@@ -9,16 +9,22 @@ class MultipleErrors extends InvalidEmail
|
|||||||
const CODE = 999;
|
const CODE = 999;
|
||||||
const REASON = "Accumulated errors for multiple validations";
|
const REASON = "Accumulated errors for multiple validations";
|
||||||
/**
|
/**
|
||||||
* @var array
|
* @var InvalidEmail[]
|
||||||
*/
|
*/
|
||||||
private $errors = [];
|
private $errors = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param InvalidEmail[] $errors
|
||||||
|
*/
|
||||||
public function __construct(array $errors)
|
public function __construct(array $errors)
|
||||||
{
|
{
|
||||||
$this->errors = $errors;
|
$this->errors = $errors;
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return InvalidEmail[]
|
||||||
|
*/
|
||||||
public function getErrors()
|
public function getErrors()
|
||||||
{
|
{
|
||||||
return $this->errors;
|
return $this->errors;
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ class MultipleValidationWithAnd implements EmailValidation
|
|||||||
private $warnings = [];
|
private $warnings = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var MultipleErrors
|
* @var MultipleErrors|null
|
||||||
*/
|
*/
|
||||||
private $error;
|
private $error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var int
|
||||||
*/
|
*/
|
||||||
private $mode;
|
private $mode;
|
||||||
|
|
||||||
@@ -79,6 +79,12 @@ class MultipleValidationWithAnd implements EmailValidation
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Egulias\EmailValidator\Exception\InvalidEmail|null $possibleError
|
||||||
|
* @param \Egulias\EmailValidator\Exception\InvalidEmail[] $errors
|
||||||
|
*
|
||||||
|
* @return \Egulias\EmailValidator\Exception\InvalidEmail[]
|
||||||
|
*/
|
||||||
private function addNewError($possibleError, array $errors)
|
private function addNewError($possibleError, array $errors)
|
||||||
{
|
{
|
||||||
if (null !== $possibleError) {
|
if (null !== $possibleError) {
|
||||||
@@ -88,6 +94,11 @@ class MultipleValidationWithAnd implements EmailValidation
|
|||||||
return $errors;
|
return $errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $result
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
private function shouldStop($result)
|
private function shouldStop($result)
|
||||||
{
|
{
|
||||||
return !$result && $this->mode === self::STOP_ON_ERROR;
|
return !$result && $this->mode === self::STOP_ON_ERROR;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use Egulias\EmailValidator\Validation\Error\RFCWarnings;
|
|||||||
class NoRFCWarningsValidation extends RFCValidation
|
class NoRFCWarningsValidation extends RFCValidation
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var InvalidEmail
|
* @var InvalidEmail|null
|
||||||
*/
|
*/
|
||||||
private $error;
|
private $error;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use Egulias\EmailValidator\Exception\InvalidEmail;
|
|||||||
class RFCValidation implements EmailValidation
|
class RFCValidation implements EmailValidation
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var EmailParser
|
* @var EmailParser|null
|
||||||
*/
|
*/
|
||||||
private $parser;
|
private $parser;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ class RFCValidation implements EmailValidation
|
|||||||
private $warnings = [];
|
private $warnings = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var InvalidEmail
|
* @var InvalidEmail|null
|
||||||
*/
|
*/
|
||||||
private $error;
|
private $error;
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use \Spoofchecker;
|
|||||||
class SpoofCheckValidation implements EmailValidation
|
class SpoofCheckValidation implements EmailValidation
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var InvalidEmail
|
* @var InvalidEmail|null
|
||||||
*/
|
*/
|
||||||
private $error;
|
private $error;
|
||||||
|
|
||||||
@@ -21,6 +21,9 @@ class SpoofCheckValidation implements EmailValidation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @psalm-suppress InvalidArgument
|
||||||
|
*/
|
||||||
public function isValid($email, EmailLexer $emailLexer)
|
public function isValid($email, EmailLexer $emailLexer)
|
||||||
{
|
{
|
||||||
$checker = new Spoofchecker();
|
$checker = new Spoofchecker();
|
||||||
@@ -33,6 +36,9 @@ class SpoofCheckValidation implements EmailValidation
|
|||||||
return $this->error === null;
|
return $this->error === null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return InvalidEmail|null
|
||||||
|
*/
|
||||||
public function getError()
|
public function getError()
|
||||||
{
|
{
|
||||||
return $this->error;
|
return $this->error;
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ class QuotedPart extends Warning
|
|||||||
{
|
{
|
||||||
const CODE = 36;
|
const CODE = 36;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param scalar $prevToken
|
||||||
|
* @param scalar $postToken
|
||||||
|
*/
|
||||||
public function __construct($prevToken, $postToken)
|
public function __construct($prevToken, $postToken)
|
||||||
{
|
{
|
||||||
$this->message = "Deprecated Quoted String found between $prevToken and $postToken";
|
$this->message = "Deprecated Quoted String found between $prevToken and $postToken";
|
||||||
|
|||||||
@@ -6,6 +6,10 @@ class QuotedString extends Warning
|
|||||||
{
|
{
|
||||||
const CODE = 11;
|
const CODE = 11;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param scalar $prevToken
|
||||||
|
* @param scalar $postToken
|
||||||
|
*/
|
||||||
public function __construct($prevToken, $postToken)
|
public function __construct($prevToken, $postToken)
|
||||||
{
|
{
|
||||||
$this->message = "Quoted String found between $prevToken and $postToken";
|
$this->message = "Quoted String found between $prevToken and $postToken";
|
||||||
|
|||||||
@@ -5,19 +5,36 @@ namespace Egulias\EmailValidator\Warning;
|
|||||||
abstract class Warning
|
abstract class Warning
|
||||||
{
|
{
|
||||||
const CODE = 0;
|
const CODE = 0;
|
||||||
protected $message;
|
|
||||||
protected $rfcNumber;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $message = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $rfcNumber = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
public function message()
|
public function message()
|
||||||
{
|
{
|
||||||
return $this->message;
|
return $this->message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function code()
|
public function code()
|
||||||
{
|
{
|
||||||
return self::CODE;
|
return self::CODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function RFCNumber()
|
public function RFCNumber()
|
||||||
{
|
{
|
||||||
return $this->rfcNumber;
|
return $this->rfcNumber;
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ use Egulias\EmailValidator\EmailValidator;
|
|||||||
use Egulias\EmailValidator\Validation\DNSCheckValidation;
|
use Egulias\EmailValidator\Validation\DNSCheckValidation;
|
||||||
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
|
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
|
||||||
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation;
|
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation;
|
||||||
use Egulias\EmailValidator\Validation\RFCValidation;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
class IsEmailFunctionTests extends TestCase
|
class IsEmailFunctionTests extends TestCase
|
||||||
|
|||||||
@@ -3,13 +3,11 @@
|
|||||||
namespace Egulias\Tests\EmailValidator\Validation;
|
namespace Egulias\Tests\EmailValidator\Validation;
|
||||||
|
|
||||||
use Egulias\EmailValidator\EmailLexer;
|
use Egulias\EmailValidator\EmailLexer;
|
||||||
use Egulias\EmailValidator\EmailValidator;
|
|
||||||
use Egulias\EmailValidator\Exception\CommaInDomain;
|
use Egulias\EmailValidator\Exception\CommaInDomain;
|
||||||
use Egulias\EmailValidator\Exception\NoDomainPart;
|
use Egulias\EmailValidator\Exception\NoDomainPart;
|
||||||
use Egulias\EmailValidator\Validation\EmailValidation;
|
use Egulias\EmailValidator\Validation\EmailValidation;
|
||||||
use Egulias\EmailValidator\Validation\MultipleErrors;
|
use Egulias\EmailValidator\Validation\MultipleErrors;
|
||||||
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
|
use Egulias\EmailValidator\Validation\MultipleValidationWithAnd;
|
||||||
use Egulias\EmailValidator\Validation\NoRFCWarningsValidation;
|
|
||||||
use Egulias\EmailValidator\Validation\RFCValidation;
|
use Egulias\EmailValidator\Validation\RFCValidation;
|
||||||
use Egulias\EmailValidator\Warning\AddressLiteral;
|
use Egulias\EmailValidator\Warning\AddressLiteral;
|
||||||
use Egulias\EmailValidator\Warning\DomainLiteral;
|
use Egulias\EmailValidator\Warning\DomainLiteral;
|
||||||
|
|||||||
+2
-1
@@ -14,7 +14,8 @@
|
|||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.5",
|
"php": ">=5.5",
|
||||||
"doctrine/lexer": "^1.0.1"
|
"doctrine/lexer": "^1.0.1",
|
||||||
|
"symfony/polyfill-intl-idn": "^1.10"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"satooshi/php-coveralls": "^1.0.1",
|
"satooshi/php-coveralls": "^1.0.1",
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<files psalm-version="3.8.3@389af1bfc739bfdff3f9e3dc7bd6499aee51a831">
|
||||||
|
<file src="EmailValidator/EmailLexer.php">
|
||||||
|
<DocblockTypeContradiction occurrences="1">
|
||||||
|
<code>self::$nullToken</code>
|
||||||
|
</DocblockTypeContradiction>
|
||||||
|
</file>
|
||||||
|
<file src="EmailValidator/Parser/Parser.php">
|
||||||
|
<MissingReturnType occurrences="1">
|
||||||
|
<code>parse</code>
|
||||||
|
</MissingReturnType>
|
||||||
|
</file>
|
||||||
|
<file src="EmailValidator/Validation/SpoofCheckValidation.php">
|
||||||
|
<UndefinedClass occurrences="2">
|
||||||
|
<code>Spoofchecker</code>
|
||||||
|
<code>Spoofchecker</code>
|
||||||
|
</UndefinedClass>
|
||||||
|
</file>
|
||||||
|
</files>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<psalm
|
||||||
|
requireVoidReturnType="false"
|
||||||
|
totallyTyped="false"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="https://getpsalm.org/schema/config"
|
||||||
|
xsi:schemaLocation="https://getpsalm.org/schema/config ./vendor/vimeo/psalm/config.xsd"
|
||||||
|
errorBaseline="./psalm.baseline.xml"
|
||||||
|
>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="EmailValidator" />
|
||||||
|
<ignoreFiles>
|
||||||
|
<directory name="vendor" />
|
||||||
|
</ignoreFiles>
|
||||||
|
</projectFiles>
|
||||||
|
|
||||||
|
<issueHandlers>
|
||||||
|
</issueHandlers>
|
||||||
|
</psalm>
|
||||||
Reference in New Issue
Block a user