Version 1
[yaffs-website] / vendor / egulias / email-validator / src / Egulias / EmailValidator / EmailLexer.php
1 <?php
2
3 namespace Egulias\EmailValidator;
4
5 use Doctrine\Common\Lexer\AbstractLexer;
6
7 class EmailLexer extends AbstractLexer
8 {
9     //ASCII values
10     const C_DEL              = 127;
11     const C_NUL              = 0;
12     const S_AT               = 64;
13     const S_BACKSLASH        = 92;
14     const S_DOT              = 46;
15     const S_DQUOTE           = 34;
16     const S_OPENPARENTHESIS  = 49;
17     const S_CLOSEPARENTHESIS = 261;
18     const S_OPENBRACKET      = 262;
19     const S_CLOSEBRACKET     = 263;
20     const S_HYPHEN           = 264;
21     const S_COLON            = 265;
22     const S_DOUBLECOLON      = 266;
23     const S_SP               = 267;
24     const S_HTAB             = 268;
25     const S_CR               = 269;
26     const S_LF               = 270;
27     const S_IPV6TAG          = 271;
28     const S_LOWERTHAN        = 272;
29     const S_GREATERTHAN      = 273;
30     const S_COMMA            = 274;
31     const S_SEMICOLON        = 275;
32     const S_OPENQBRACKET     = 276;
33     const S_CLOSEQBRACKET    = 277;
34     const S_SLASH            = 278;
35     const S_EMPTY            = null;
36     const GENERIC            = 300;
37     const CRLF               = 301;
38     const INVALID            = 302;
39     const ASCII_INVALID_FROM = 127;
40     const ASCII_INVALID_TO   = 199;
41
42     /**
43      * US-ASCII visible characters not valid for atext (@link http://tools.ietf.org/html/rfc5322#section-3.2.3)
44      *
45      * @var array
46      */
47     protected $charValue = array(
48         '('    => self::S_OPENPARENTHESIS,
49         ')'    => self::S_CLOSEPARENTHESIS,
50         '<'    => self::S_LOWERTHAN,
51         '>'    => self::S_GREATERTHAN,
52         '['    => self::S_OPENBRACKET,
53         ']'    => self::S_CLOSEBRACKET,
54         ':'    => self::S_COLON,
55         ';'    => self::S_SEMICOLON,
56         '@'    => self::S_AT,
57         '\\'   => self::S_BACKSLASH,
58         '/'    => self::S_SLASH,
59         ','    => self::S_COMMA,
60         '.'    => self::S_DOT,
61         '"'    => self::S_DQUOTE,
62         '-'    => self::S_HYPHEN,
63         '::'   => self::S_DOUBLECOLON,
64         ' '    => self::S_SP,
65         "\t"   => self::S_HTAB,
66         "\r"   => self::S_CR,
67         "\n"   => self::S_LF,
68         "\r\n" => self::CRLF,
69         'IPv6' => self::S_IPV6TAG,
70         '{'    => self::S_OPENQBRACKET,
71         '}'    => self::S_CLOSEQBRACKET,
72         ''     => self::S_EMPTY,
73         '\0'   => self::C_NUL,
74     );
75
76     protected $hasInvalidTokens = false;
77
78     protected $previous;
79
80     public function reset()
81     {
82         $this->hasInvalidTokens = false;
83         parent::reset();
84     }
85
86     public function hasInvalidTokens()
87     {
88         return $this->hasInvalidTokens;
89     }
90
91     /**
92      * @param $type
93      * @throws \UnexpectedValueException
94      * @return boolean
95      */
96     public function find($type)
97     {
98         $search = clone $this;
99         $search->skipUntil($type);
100
101         if (!$search->lookahead) {
102             throw new \UnexpectedValueException($type . ' not found');
103         }
104         return true;
105     }
106
107     /**
108      * getPrevious
109      *
110      * @return array token
111      */
112     public function getPrevious()
113     {
114         return $this->previous;
115     }
116
117     /**
118      * moveNext
119      *
120      * @return boolean
121      */
122     public function moveNext()
123     {
124         $this->previous = $this->token;
125
126         return parent::moveNext();
127     }
128
129     /**
130      * Lexical catchable patterns.
131      *
132      * @return string[]
133      */
134     protected function getCatchablePatterns()
135     {
136         return array(
137             '[a-zA-Z_]+[46]?', //ASCII and domain literal
138             '[^\x00-\x7F]',  //UTF-8
139             '[0-9]+',
140             '\r\n',
141             '::',
142             '\s+?',
143             '.',
144             );
145     }
146
147     /**
148      * Lexical non-catchable patterns.
149      *
150      * @return string[]
151      */
152     protected function getNonCatchablePatterns()
153     {
154         return array('[\xA0-\xff]+');
155     }
156
157     /**
158      * Retrieve token type. Also processes the token value if necessary.
159      *
160      * @param string $value
161      * @throws \InvalidArgumentException
162      * @return integer
163      */
164     protected function getType(&$value)
165     {
166         if ($this->isNullType($value)) {
167             return self::C_NUL;
168         }
169
170         if ($this->isValid($value)) {
171             return $this->charValue[$value];
172         }
173
174         if ($this->isUTF8Invalid($value)) {
175             $this->hasInvalidTokens = true;
176             return self::INVALID;
177         }
178
179         return  self::GENERIC;
180     }
181
182     protected function isValid($value)
183     {
184         if (isset($this->charValue[$value])) {
185             return true;
186         }
187
188         return false;
189     }
190
191     /**
192      * @param $value
193      * @return bool
194      */
195     protected function isNullType($value)
196     {
197         if ($value === "\0") {
198             return true;
199         }
200
201         return false;
202     }
203
204     /**
205      * @param $value
206      * @return bool
207      */
208     protected function isUTF8Invalid($value)
209     {
210         if (preg_match('/\p{Cc}+/u', $value)) {
211             return true;
212         }
213
214         return false;
215     }
216
217     protected function getModifiers()
218     {
219         return 'iu';
220     }
221 }