1<?php 2 3namespace Egulias\EmailValidator; 4 5use Egulias\EmailValidator\Exception\ExpectingATEXT; 6use Egulias\EmailValidator\Exception\NoLocalPart; 7use Egulias\EmailValidator\Parser\DomainPart; 8use Egulias\EmailValidator\Parser\LocalPart; 9use Egulias\EmailValidator\Warning\EmailTooLong; 10 11/** 12 * EmailParser 13 * 14 * @author Eduardo Gulias Davis <me@egulias.com> 15 */ 16class EmailParser 17{ 18 const EMAIL_MAX_LENGTH = 254; 19 20 protected $warnings; 21 protected $domainPart = ''; 22 protected $localPart = ''; 23 protected $lexer; 24 protected $localPartParser; 25 protected $domainPartParser; 26 27 public function __construct(EmailLexer $lexer) 28 { 29 $this->lexer = $lexer; 30 $this->localPartParser = new LocalPart($this->lexer); 31 $this->domainPartParser = new DomainPart($this->lexer); 32 $this->warnings = new \SplObjectStorage(); 33 } 34 35 /** 36 * @param $str 37 * @return array 38 */ 39 public function parse($str) 40 { 41 $this->lexer->setInput($str); 42 43 if (!$this->hasAtToken()) { 44 throw new NoLocalPart(); 45 } 46 47 48 $this->localPartParser->parse($str); 49 $this->domainPartParser->parse($str); 50 51 $this->setParts($str); 52 53 if ($this->lexer->hasInvalidTokens()) { 54 throw new ExpectingATEXT(); 55 } 56 57 return array('local' => $this->localPart, 'domain' => $this->domainPart); 58 } 59 60 public function getWarnings() 61 { 62 $localPartWarnings = $this->localPartParser->getWarnings(); 63 $domainPartWarnings = $this->domainPartParser->getWarnings(); 64 $this->warnings = array_merge($localPartWarnings, $domainPartWarnings); 65 66 $this->addLongEmailWarning($this->localPart, $this->domainPart); 67 68 return $this->warnings; 69 } 70 71 public function getParsedDomainPart() 72 { 73 return $this->domainPart; 74 } 75 76 protected function setParts($email) 77 { 78 $parts = explode('@', $email); 79 $this->domainPart = $this->domainPartParser->getDomainPart(); 80 $this->localPart = $parts[0]; 81 } 82 83 protected function hasAtToken() 84 { 85 $this->lexer->moveNext(); 86 $this->lexer->moveNext(); 87 if ($this->lexer->token['type'] === EmailLexer::S_AT) { 88 return false; 89 } 90 91 return true; 92 } 93 94 /** 95 * @param string $localPart 96 * @param string $parsedDomainPart 97 */ 98 protected function addLongEmailWarning($localPart, $parsedDomainPart) 99 { 100 if (strlen($localPart . '@' . $parsedDomainPart) > self::EMAIL_MAX_LENGTH) { 101 $this->warnings[EmailTooLong::CODE] = new EmailTooLong(); 102 } 103 } 104} 105