mirror of
https://github.com/egulias/EmailValidator.git
synced 2026-09-16 04:56:47 +00:00
Part extraction improvement with lexer recording. Reported in #181
This commit is contained in:
@@ -110,6 +110,9 @@ class EmailLexer extends AbstractLexer
|
||||
'position' => 0,
|
||||
];
|
||||
|
||||
private $accumulator = '';
|
||||
private $hasToRecord = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->previous = $this->token = self::$nullToken;
|
||||
@@ -169,10 +172,18 @@ class EmailLexer extends AbstractLexer
|
||||
*/
|
||||
public function moveNext()
|
||||
{
|
||||
if ($this->hasToRecord && $this->previous === self::$nullToken) {
|
||||
$this->accumulator .= $this->token['value'];
|
||||
}
|
||||
|
||||
$this->previous = $this->token;
|
||||
$hasNext = parent::moveNext();
|
||||
$this->token = $this->token ?: self::$nullToken;
|
||||
|
||||
if ($this->hasToRecord) {
|
||||
$this->accumulator .= $this->token['value'];
|
||||
}
|
||||
|
||||
return $hasNext;
|
||||
}
|
||||
|
||||
@@ -276,4 +287,24 @@ class EmailLexer extends AbstractLexer
|
||||
{
|
||||
return 'iu';
|
||||
}
|
||||
|
||||
public function getAccumulatedValues() : string
|
||||
{
|
||||
return $this->accumulator;
|
||||
}
|
||||
|
||||
public function startRecording() : void
|
||||
{
|
||||
$this->hasToRecord = true;
|
||||
}
|
||||
|
||||
public function stopRecording() : void
|
||||
{
|
||||
$this->hasToRecord = false;
|
||||
}
|
||||
|
||||
public function clearRecorded() : void
|
||||
{
|
||||
$this->accumulator = '';
|
||||
}
|
||||
}
|
||||
|
||||
+34
-26
@@ -12,11 +12,6 @@ use Egulias\EmailValidator\Warning\EmailTooLong;
|
||||
use Egulias\EmailValidator\Result\Reason\ExpectingATEXT;
|
||||
use Egulias\EmailValidator\Result\Reason\NoLocalPart;
|
||||
|
||||
/**
|
||||
* EmailParser
|
||||
*
|
||||
* @author Eduardo Gulias Davis <me@egulias.com>
|
||||
*/
|
||||
class EmailParser
|
||||
{
|
||||
const EMAIL_MAX_LENGTH = 254;
|
||||
@@ -53,8 +48,6 @@ class EmailParser
|
||||
public function __construct(EmailLexer $lexer)
|
||||
{
|
||||
$this->lexer = $lexer;
|
||||
$this->localPartParser = new LocalPart($this->lexer);
|
||||
$this->domainPartParser = new DomainPart($this->lexer);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,24 +62,50 @@ class EmailParser
|
||||
return new InvalidEmail(new NoLocalPart(), $this->lexer->token["value"]);
|
||||
}
|
||||
|
||||
$localPartResult = $this->localPartParser->parse();
|
||||
$localPartResult = $this->processLocalPart();
|
||||
|
||||
if ($localPartResult->isInvalid()) {
|
||||
return $localPartResult;
|
||||
}
|
||||
|
||||
$domainPartResult = $this->domainPartParser->parse();
|
||||
$domainPartResult = $this->processDomainPart();
|
||||
|
||||
if ($domainPartResult->isInvalid()) {
|
||||
return $domainPartResult;
|
||||
}
|
||||
|
||||
$this->setParts($str);
|
||||
|
||||
if ($this->lexer->hasInvalidTokens()) {
|
||||
return new InvalidEmail(new ExpectingATEXT("Invalid tokens found"), $this->lexer->token["value"]);
|
||||
}
|
||||
|
||||
$this->addLongEmailWarning($this->localPart, $this->domainPart);
|
||||
|
||||
return new ValidEmail();
|
||||
//return array('local' => $this->localPart, 'domain' => $this->domainPart);
|
||||
}
|
||||
|
||||
private function processLocalPart() : Result
|
||||
{
|
||||
$this->lexer->startRecording();
|
||||
$this->localPartParser = new LocalPart($this->lexer);
|
||||
$localPartResult = $this->localPartParser->parse();
|
||||
$this->lexer->stopRecording();
|
||||
$this->localPart = rtrim($this->lexer->getAccumulatedValues(), '@');
|
||||
$this->warnings = array_merge($this->localPartParser->getWarnings(), $this->warnings);
|
||||
|
||||
return $localPartResult;
|
||||
}
|
||||
|
||||
private function processDomainPart() : Result
|
||||
{
|
||||
$this->lexer->clearRecorded();
|
||||
$this->lexer->startRecording();
|
||||
$this->domainPartParser = new DomainPart($this->lexer);
|
||||
$domainPartResult = $this->domainPartParser->parse();
|
||||
$this->lexer->stopRecording();
|
||||
$this->domainPart = $this->lexer->getAccumulatedValues();
|
||||
$this->warnings = array_merge($this->domainPartParser->getWarnings(), $this->warnings);
|
||||
|
||||
return $domainPartResult;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,31 +113,20 @@ class EmailParser
|
||||
*/
|
||||
public function getWarnings() : array
|
||||
{
|
||||
$localPartWarnings = $this->localPartParser->getWarnings();
|
||||
$domainPartWarnings = $this->domainPartParser->getWarnings();
|
||||
$this->warnings = array_merge($localPartWarnings, $domainPartWarnings);
|
||||
|
||||
$this->addLongEmailWarning($this->localPart, $this->domainPart);
|
||||
|
||||
return $this->warnings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getParsedDomainPart() : string
|
||||
public function getDomainPart() : string
|
||||
{
|
||||
return $this->domainPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $email
|
||||
*/
|
||||
protected function setParts($email) : void
|
||||
public function getLocalPart() : string
|
||||
{
|
||||
$parts = explode('@', $email);
|
||||
$this->domainPart = $this->domainPartParser->getDomainPart();
|
||||
$this->localPart = $parts[0];
|
||||
return $this->localPart;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -159,4 +159,33 @@ class EmailLexerTests extends TestCase
|
||||
array(chr(0), EmailLexer::C_NUL)
|
||||
);
|
||||
}
|
||||
|
||||
public function testRecordIsOffAtStart()
|
||||
{
|
||||
$lexer = new EmailLexer();
|
||||
$lexer->setInput('foo-bar');
|
||||
$lexer->moveNext();
|
||||
$this->assertEquals('', $lexer->getAccumulatedValues());
|
||||
}
|
||||
|
||||
public function testRecord()
|
||||
{
|
||||
$lexer = new EmailLexer();
|
||||
$lexer->setInput('foo-bar');
|
||||
$lexer->startRecording();
|
||||
$lexer->moveNext();
|
||||
$lexer->moveNext();
|
||||
$this->assertEquals('foo', $lexer->getAccumulatedValues());
|
||||
}
|
||||
|
||||
public function testRecordAndClear()
|
||||
{
|
||||
$lexer = new EmailLexer();
|
||||
$lexer->setInput('foo-bar');
|
||||
$lexer->startRecording();
|
||||
$lexer->moveNext();
|
||||
$lexer->moveNext();
|
||||
$lexer->clearRecorded();
|
||||
$this->assertEquals('', $lexer->getAccumulatedValues());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Egulias\EmailValidator\Tests\EmailValidator;
|
||||
|
||||
use Egulias\EmailValidator\EmailLexer;
|
||||
use Egulias\EmailValidator\EmailParser;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class EmailParserTests extends TestCase
|
||||
{
|
||||
public function emailPartsProvider()
|
||||
{
|
||||
return [
|
||||
['test@foo.com', 'test', 'foo.com'],
|
||||
['"user@name"@example.com', '"user@name"', 'example.com'],
|
||||
['validipv6@[IPv6:2001:db8:1ff::a0b:dbd0]', 'validipv6', '[IPv6:2001:db8:1ff::a0b:dbd0]'],
|
||||
['validipv4@[127.0.0.0]', 'validipv4', '[127.0.0.0]']
|
||||
];
|
||||
}
|
||||
/**
|
||||
* @dataProvider emailPartsProvider
|
||||
*/
|
||||
public function testGetParts($email, $local, $domain)
|
||||
{
|
||||
$parser = new EmailParser(new EmailLexer());
|
||||
$parser->parse($email);
|
||||
|
||||
$this->assertEquals($local, $parser->getLocalPart());
|
||||
$this->assertEquals($domain, $parser->getDomainPart());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user