Revision 148 | Blame | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed
<?phpnamespace Egulias\EmailValidator\Parser;use Egulias\EmailValidator\EmailLexer;use Egulias\EmailValidator\Result\Result;use Egulias\EmailValidator\Result\ValidEmail;use Egulias\EmailValidator\Result\InvalidEmail;use Egulias\EmailValidator\Warning\LocalTooLong;use Egulias\EmailValidator\Result\Reason\DotAtEnd;use Egulias\EmailValidator\Result\Reason\DotAtStart;use Egulias\EmailValidator\Result\Reason\ConsecutiveDot;use Egulias\EmailValidator\Result\Reason\ExpectingATEXT;use Egulias\EmailValidator\Parser\CommentStrategy\LocalComment;class LocalPart extends PartParser{public const INVALID_TOKENS = [EmailLexer::S_COMMA => EmailLexer::S_COMMA,EmailLexer::S_CLOSEBRACKET => EmailLexer::S_CLOSEBRACKET,EmailLexer::S_OPENBRACKET => EmailLexer::S_OPENBRACKET,EmailLexer::S_GREATERTHAN => EmailLexer::S_GREATERTHAN,EmailLexer::S_LOWERTHAN => EmailLexer::S_LOWERTHAN,EmailLexer::S_COLON => EmailLexer::S_COLON,EmailLexer::S_SEMICOLON => EmailLexer::S_SEMICOLON,EmailLexer::INVALID => EmailLexer::INVALID];/*** @var string*/private $localPart = '';public function parse(): Result{$this->lexer->startRecording();while (!$this->lexer->current->isA(EmailLexer::S_AT) && !$this->lexer->current->isA(EmailLexer::S_EMPTY)) {if ($this->hasDotAtStart()) {return new InvalidEmail(new DotAtStart(), $this->lexer->current->value);}if ($this->lexer->current->isA(EmailLexer::S_DQUOTE)) {$dquoteParsingResult = $this->parseDoubleQuote();//Invalid double quote parsingif ($dquoteParsingResult->isInvalid()) {return $dquoteParsingResult;}}if ($this->lexer->current->isA(EmailLexer::S_OPENPARENTHESIS) ||$this->lexer->current->isA(EmailLexer::S_CLOSEPARENTHESIS)) {$commentsResult = $this->parseComments();//Invalid comment parsingif ($commentsResult->isInvalid()) {return $commentsResult;}}if ($this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->isNextToken(EmailLexer::S_DOT)) {return new InvalidEmail(new ConsecutiveDot(), $this->lexer->current->value);}if ($this->lexer->current->isA(EmailLexer::S_DOT) &&$this->lexer->isNextToken(EmailLexer::S_AT)) {return new InvalidEmail(new DotAtEnd(), $this->lexer->current->value);}$resultEscaping = $this->validateEscaping();if ($resultEscaping->isInvalid()) {return $resultEscaping;}$resultToken = $this->validateTokens(false);if ($resultToken->isInvalid()) {return $resultToken;}$resultFWS = $this->parseLocalFWS();if ($resultFWS->isInvalid()) {return $resultFWS;}$this->lexer->moveNext();}$this->lexer->stopRecording();$this->localPart = rtrim($this->lexer->getAccumulatedValues(), '@');if (strlen($this->localPart) > LocalTooLong::LOCAL_PART_LENGTH) {$this->warnings[LocalTooLong::CODE] = new LocalTooLong();}return new ValidEmail();}protected function validateTokens(bool $hasComments): Result{if (isset(self::INVALID_TOKENS[$this->lexer->current->type])) {return new InvalidEmail(new ExpectingATEXT('Invalid token found'), $this->lexer->current->value);}return new ValidEmail();}public function localPart(): string{return $this->localPart;}private function parseLocalFWS(): Result{$foldingWS = new FoldingWhiteSpace($this->lexer);$resultFWS = $foldingWS->parse();if ($resultFWS->isValid()) {$this->warnings = array_merge($this->warnings, $foldingWS->getWarnings());}return $resultFWS;}private function hasDotAtStart(): bool{return $this->lexer->current->isA(EmailLexer::S_DOT) && $this->lexer->getPrevious()->isA(EmailLexer::S_EMPTY);}private function parseDoubleQuote(): Result{$dquoteParser = new DoubleQuote($this->lexer);$parseAgain = $dquoteParser->parse();$this->warnings = array_merge($this->warnings, $dquoteParser->getWarnings());return $parseAgain;}protected function parseComments(): Result{$commentParser = new Comment($this->lexer, new LocalComment());$result = $commentParser->parse();$this->warnings = array_merge($this->warnings, $commentParser->getWarnings());if ($result->isInvalid()) {return $result;}return $result;}private function validateEscaping(): Result{//Backslash foundif (!$this->lexer->current->isA(EmailLexer::S_BACKSLASH)) {return new ValidEmail();}if ($this->lexer->isNextToken(EmailLexer::GENERIC)) {return new InvalidEmail(new ExpectingATEXT('Found ATOM after escaping'), $this->lexer->current->value);}if (!$this->lexer->isNextTokenAny(array(EmailLexer::S_SP, EmailLexer::S_HTAB, EmailLexer::C_DEL))) {return new ValidEmail();}return new ValidEmail();}}